Cómo silenciar una advertencia en rápido

98

Tengo un fragmento de código que genera muchas advertencias (API obsoleta)

Usando clang * podría hacer

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    ...
#pragma clang diagnostic pop

Sin embargo, esto no funciona con rapidez.

¿Cómo hacerlo en rápido?

Nota: No quiero deshabilitar la advertencia de forma global, ni siquiera en todo el archivo, solo deshabilito una advertencia específica en una parte específica de mi código fuente.

Editar: parece que mi nota no fue lo suficientemente clara: NO quiero una compilación condicional (que es la respuesta propuesta del supuesto duplicado). Solo quiero silenciar una advertencia SIN usar las nuevas API.

Antzi
fuente
4
Este no es un duplicado. La otra pregunta no responde a este problema.
Claus Jørgensen
@ ClausJørgensen ¿de qué manera no responde a este problema? No hay otra forma como se indica en las respuestas en la pregunta vinculada. Solo compilación condicional o nueva #availablemacro donde el desarrollador debe usar nuevos métodos y recurrir a los antiguos si no hay nuevos disponibles.
zrzka
@robertvojta No, ya que las respuestas, de hecho, no indican que no hay otras formas de silenciar una advertencia.
Claus Jørgensen
2
Esto no es un engaño. ¿Qué pasa con una situación en la que recibe una advertencia por perder un inicializador?
NSTJ

Respuestas:

157

A partir de 2020, Xcode 12.0, el consenso es que no hay forma de lograrlo.

Actualizaré / editaré esta respuesta si Apple agrega la función.

¡Ponlo en tu lista de deseos para la WWDC 2021!

Antzi
fuente
21
Maldita sea, eso es un fastidio. A veces se sale de control . Es molesto por decir lo menos.
Isuru
2
Quiero rechazar esta respuesta un millón de veces, pero responde bastante bien a la pregunta, así que +1 :-)
deadbeef
3
@Isuru En ese punto, me irritaba lo suficiente como para reconstruir todo. Supongo que las advertencias funcionaron
Sirens
1
@Isuru La mayoría de ellos deben arreglarse, no ignorarse.
Kevin
3
¡Muy frustrante! Gracias por mantener actualizada esta respuesta.
Dan Loewenherz
48

No existe una construcción general para silenciar las advertencias de obsolescencia en Swift, pero hay una solución que se puede aplicar en muchos casos .

Digamos que tiene un método getLatestImage()en la clase Fooque usa métodos / clases obsoletos.

Use @availablecomo lo describió Daniel Thorpe para silenciar todas las advertencias dentro del método:

@available(iOS, deprecated: 9.0)
func getLatestImage() -> UIImage? {
    ...
}

Ahora le gustaría llamar al método getLatestImage()sin tener una advertencia de obsolescencia. Puede lograrlo definiendo primero un protocolo y una extensión:

private protocol GetLatestImage {
    func getLatestImage() -> UIImage?
}
extension Foo: GetLatestImage {}

Y luego llame al método sin una advertencia de desaprobación (si fooes una instancia de Foo):

(foo as GetLatestImage).getLatestImage() // no deprecation warning

El resultado es que tiene un código Swift que usa una API obsoleta sin advertencias de obsolescencia.

Tammo Freese
fuente
Tan inteligente. ¿Tipo de maldad? :) Pero muy bien. Excelente para un caso de uso como suprimir las advertencias sobre el uso continuo de algunos aspectos del marco de AddressBook que han quedado en desuso, pero que tienen un reemplazo que aún no proporciona todas las funciones requeridas. Gracias.
Duncan Babbage
4
Si esto funciona, le enviaré un paquete de seis de su bebida favorita. tiene una mente excelente señor, gracias.
John
@John ¡Gracias por tus amables palabras! Funciona, tuve que idearlo ya que tratamos las advertencias como errores en nuestra base de código, y hay una sección que todavía usa una biblioteca obsoleta.
Tammo Freese
1
@John, ¿le enviaste el paquete de seis? : P Esto es asombroso. Genio. Gracias.
Baran Emre
Eres un genio malvado.
Krypt
37

En realidad, puede suprimir estas advertencias mediante el uso @availablede la estructura lógica adjunta (es decir, función / tipo).

Por ejemplo, digamos que tiene un código que usa el marco de la libreta de direcciones, pero está construyendo contra iOS 9.

@available(iOS, deprecated: 9.0)
func addressBookStatus() -> ABAuthorizationStatus {
    return ABAddressBookGetAuthorizationStatus()
}

A partir de Xcode 7.0.1, esto evitará que se muestren las advertencias en línea.

Daniel Thorpe
fuente
6
Sí, pero verá la misma advertencia cuando llame a su addressBookStatus()... que marca como obsoleto.
Valentin Shergin
3
Pro consejo: si quiere silenciarla durante toda una clase solo golpe este cachorro por encima de su declaración de clase (por ejemplo: class ViewController: UIViewController)
Las sirenas
2
@Sirens Entonces verá esta advertencia cada vez que llame a esta clase ☹️ (al menos con Xcode 8)
Alexander Vasenin
¿Alguien logró silenciar todas las advertencias obsoletas con esta solución? Pude disminuir su número a solo uno , pero no veo la manera de deshacerme del último. ¿Alguna sugerencia?
Alexander Vasenin
1
Entonces, ¿cómo usar esto para silenciar la advertencia "emitir desde 'CGFloat.NativeType' (también conocido como 'Double') al tipo no relacionado 'Float' siempre falla" cuando estoy haciendo un if CGFloat(0).native is Float { … }? Respuesta: No uso esto porque no respondió la pregunta.
Slipp D. Thompson
1

Si bien no hay forma de silenciar las advertencias de desaprobación en Swift por ahora, técnicamente puede hacerlo para un símbolo en particular editando el archivo de encabezado.

  • Copie el nombre del símbolo obsoleto
  • Seleccione File>Open Quickly
  • Pega el símbolo y presiona Enter

    Asegúrese de que el icono de Swift esté desactivado en el cuadro Abrir rápidamente

  • Seleccione File>Show in Finder

  • Cambie los permisos de archivo para permitir la edición si es necesario
  • Edite las macros de obsolescencia del símbolo. Consulte las API circundantes como referencia. Por ejemplo, reemplazar:

__OSX_AVAILABLE_BUT_DEPRECATED (__ MAC_10_6, __MAC_10_10, __IPHONE_3_0, __IPHONE_8_0)

con

__OSX_AVAILABLE_STARTING (__ MAC_10_6, __IPHONE_3_0)

Ahora hay una advertencia menos molesta sobre la que no puede hacer nada.

Lo sé, está sucio. Pero si no hay una API de reemplazo disponible en el SDK actual, debería ser seguro. Una vez que salga una nueva versión de Xcode, el cambio se sobrescribirá y volverá a ver la advertencia. Luego, puede probar el nuevo SDK y el sistema operativo para asegurarse de que la API obsoleta aún esté disponible y no haya recibido un reemplazo.

Por favor comente si se le ocurre alguna desventaja.

pointum
fuente
Voto a favor por el ingenio, pero dejaría un sabor sucio en mi boca: P
Matt