swift xcode macros versioning

¿Cuál es el equivalente de Swift de “#ifdef__IPHONE_11_0” de Objective-C?



xcode macros (4)

El iOS 11 SDK viene con Swift 3.2 (o Swift 4), por lo que puedes usar una versión de Swift para lograr lo mismo:

#if swift(>=3.2) if #available(iOS 11.0, *) { … } #endif

Quiero usar Xcode 9 para agregar el código de iOS 11 a mi proyecto mientras mantengo la opción de compilar el proyecto con Xcode 8 que solo es compatible con iOS 10.

En Objective-C puedo hacer esto usando una directiva de preprocesador para verificar si __IPHONE_11_0 está definido. Lo que esconderá el código si compilo con un SDK básico anterior a iOS 11. Así:

#ifdef __IPHONE_11_0 if (@available(iOS 11.0, *)) { self.navigationController.navigationBar.prefersLargeTitles = YES; } #endif

¿Hay una manera de hacer eso en Swift?

if #available(iOS 11.0, *) no funciona porque es una verificación de tiempo de ejecución.


Entiendo. Tengo un Mac viejo que me gusta usar que es demasiado viejo para Xcode 9, así que también quiero poder compilar mis proyectos a veces bajo Xcode 8.

Pero si lo único que desea es que sea compatible con iOS 10 y iOS 11, la forma más sencilla es establecer el SDK mínimo del destino de Xcode en 10.0 y compilar siempre con el SDK de iOS 11. Swift funcionará para usted en ese caso, y le dará errores de sintaxis a menos que lo use correctamente si #available (iOS 11.0, *) {

Aún podrás probar tanto en iOS 10 como en iOS 11 y no tendrás que preocuparte por Xcode 8.

Desde el punto de vista de Xcode 8, está intentando compilar el código fuente del futuro. No hay una buena solución para Xcode 8.

En el futuro, aquí está la solución:

En Xcode 9.3 (Swift 4.1), puedes decir:

#if canImport(MagiciOS12Kit) if #available(iOS 12.0, *) { MagiciOS12Class.standard.method() } #endif

y su código aún se compilará bajo Xcode 9.3, pero se salteará esas cosas futuras que necesitan un Xcode hipotético 10.0 o posterior.

#if canImport (moduleName) solo se agregó en Swift 4.1, que Xcode 8 no puede manejar. Pero incluso esto solo funciona para módulos completos que Apple agrega en el futuro. Si Apple simplemente amplía una clase existente con nuevos métodos, como en su navigationController.navigationBar.prefersLargeTitles , todavía no podrá probar los prefersLargeTitles directamente, pero puede encontrar otro marco que Apple introdujo al mismo tiempo que prefersLargeTitles y verifique la existencia de ese marco con #if canImport (…) .


Esta es la solución sugerida por Apple:

if #available(iOS 11.0, *) { // iOS 11 specific stuff here } else { // non iOS 11 stuff here }

Por favor, consulte estos recursos (vea el video en la marca 6:50 para más detalles)


Si desea poner la condición fuera de la función, puede hacerlo como se muestra a continuación.

@available(iOS 11.0, *) func functionName() { // function contents }