Alternativa rápida para el diagnóstico de #pragma clang
Problema
Recientemente encontré una advertencia en una utilidad de terceros (WEPopover) en este fragmento de código:
_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;
Esto generaba la siguiente advertencia:
warning: 'contentSizeForViewInPopover' is deprecated: first deprecated in iOS 7.0 - Use UIViewController.preferredContentSize instead. [-Wdeprecated-declarations]
_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;
Una solución temporal para esto en Objective-C es utilizar el diagnóstico de pragma clang para silenciar el error (dejaré que el autor del código se ocupe de una solución verdadera). Así que revisé el código así:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;
#pragma clang diagnostic pop
Pregunta
Lo que funciona bien, pero esto me llevó a considerar qué pasa si existe alguna alternativa en la que uno tendría que silenciar una advertencia de falsos positivos similar al codificar en Swift.
Consideraciones
He observado el hecho de que puedo desactivar tales advertencias en todo el proyecto (usando la configuración de Xcode) pero quiero considerar el problema en línea como se señaló anteriormente. También he considerado agregar un #define en un archivo .bridging-header.h dentro de mi proyecto Swift y de alguna manera hacer uso de eso; Sin embargo, estoy buscando una solución específica de Swift para este problema. Entiendo que pragma ya no está disponible y busqué SO y encontré preguntas similares pero no duplicadas.
RESOLUCIÓN ACTUALIZADA: Swift 2.0
La respuesta proporcionada maneja mi preocupación sobre las advertencias en línea. El comando de disponibilidad debería permitir que tales problemas se eviten por completo porque uno sería advertido en tiempo de compilación.
El libro Swift de Apple declara definitivamente:
"Se utiliza una condición de disponibilidad en una instrucción if o guard para ejecutar condicionalmente un bloque de código, dependiendo de si las API que desea utilizar están disponibles en tiempo de ejecución. El compilador utiliza la información de la condición de disponibilidad cuando verifica que las API en ese "bloque de código están disponibles".
if #available(iOS 9, OSX 10.10, *) {
// Use iOS 9 APIs on iOS, and use OS X v10.10 APIs on OS X
} else {
// Fall back to earlier iOS and OS X APIs
}
”
Extracto de: Apple Inc. "El lenguaje de programación Swift (Presentación preliminar de Swift 2)". IBooks.https://itun.es/us/k5SW7.l ”
Incluso se podría usar la declaración de protección combinada con la disponibilidad para salir del alcance antes de tiempo a menos que se cumplan las condiciones disponibles.
guard #available(iOS 8.0, OSX 10.10, *) else { return }
Extracto de: Apple Inc. "Uso de Swift con Cocoa y Objective-C (Presentación preliminar de Swift 2)". IBooks.https://itun.es/us/utTW7.l
Además, mis preocupaciones relacionadas con el manejo de macros se abordan como se indica a continuación. Teniendo en cuenta que Swift no tiene un preprocesador, estas herramientas parecen ser el camino a seguir.
“Macros simples
Cuando solía utilizar la directiva #define para definir una constante primitiva en C y Objective-C, en Swift utiliza una constante global. Por ejemplo, la definición constante #define FADE_ANIMATION_DURATION 0.35 se puede expresar mejor en Swift con let FADE_ANIMATION_DURATION = 0.35. Debido a que las macros simples de tipo constante se asignan directamente a las variables globales de Swift, el compilador importa automáticamente las macros simples definidas en los archivos fuente C y Objective-C ".
Extracto de: Apple Inc. "Uso de Swift con Cocoa y Objective-C (Presentación preliminar de Swift 2)". IBooks.https://itun.es/us/utTW7.l
“Macros complejas
Las macros complejas se usan en C y Objective-C pero no tienen contrapartida en Swift. Las macros complejas son macros que no definen constantes, incluidas las macros parecidas a funciones entre paréntesis. Utiliza macros complejas en C y Objective-C para evitar restricciones de verificación de tipo o para evitar volver a escribir grandes cantidades de código repetitivo. Sin embargo, las macros pueden dificultar la depuración y la refactorización. En Swift, puede usar funciones y genéricos para lograr los mismos resultados sin ningún compromiso. Por lo tanto, las "macros complejas que se encuentran en los archivos fuente C y Objective-C no están disponibles para su código Swift".
Extracto de: Apple Inc. "Uso de Swift con Cocoa y Objective-C (Presentación preliminar de Swift 2)". IBooks.https://itun.es/us/utTW7.l
El desarrollador de la API podrá marcar la disponibilidad de funciones en Swift usando:
available(iOS 8.0, OSX 10.10, *)
func useShinyNewFeature() {
// ...
}
Extracto de: Apple Inc. "Uso de Swift con Cocoa y Objective-C (Presentación preliminar de Swift 2)". IBooks.https://itun.es/us/utTW7.l
Agregar estos marcadores a las funciones reescritas para Swift parece una buena manera de mantener la compatibilidad con versiones anteriores de Frameworks. La combinación guardia / disponible permitirá a los usuarios de esos marcos ajustar la lógica según sea necesario. Lo que me tranquiliza sobre cómo manejar las advertencias en línea, el retroceso de API y las macros en general.