Francisco José García Navarro
Francisco José García Navarro
June 11, 2024

WWDC 2024: todo lo que un desarrollador iOS necesita saber

WWDC 2024: todo lo que un desarrollador iOS necesita saber
" El resumen técnico del día después — Swift 6, Apple Intelligence, Swift Testing y el mayor cambio en concurrencia desde async/await "

Acabo de terminar de ver el keynote y el State of the Union de la WWDC 2024, y necesito decirlo claramente: esta es la WWDC más importante desde 2019, cuando Apple lanzó SwiftUI y Combine. Y posiblemente más.

Swift 6 llega con seguridad frente a data races en tiempo de compilación. Apple Intelligence mete IA generativa en el sistema operativo. Un nuevo framework de testing reemplaza la forma en que escribimos tests desde hace una década. Y SwiftData por fin permite custom backends.

Pero lo que más me impacta no son las features individuales — es que Apple está cerrando un arco que empezó en 2020 con los actores y async/await. Swift 6 es la culminación de ese camino: concurrencia segura por defecto, sin opción a ignorarla. Y eso va a doler en apps enterprise con millones de líneas de código.

Swift 6: seguridad frente a data races en compilación

Esta es la noticia más importante de la WWDC para cualquier developer iOS. Swift 6 language mode convierte los warnings de concurrencia en errores de compilación. Si tu código tiene un data race potencial, no compila. Punto.

Esto extiende las garantías de seguridad de memoria que Swift ya tenía (null safety, bounds checking) al territorio de la concurrencia: actores, Sendable, fronteras de aislamiento — todo se verifica de forma estricta.

La clave técnica que hace esto viable es SE-0414: Region-based Isolation. El compilador realiza análisis de flujo para demostrar cuándo valores no-Sendable pueden cruzar fronteras de aislamiento de forma segura. Esto reduce drásticamente los falsos positivos que hacían inviable el strict concurrency checking en Swift 5. Complementa esto la nueva keyword sending (SE-0430), que marca explícitamente parámetros y valores de retorno que cruzan dominios de aislamiento.

Lo más importante para equipos enterprise: la migración es incremental. El compilador de Swift 6 viene con Xcode 16 y compila tu código existente sin cambios. Optas al language mode Swift 6 por target, con SWIFT_LANGUAGE_MODE = 6 en build settings o .swiftLanguageMode(.v6) en Package.swift. Módulos compilados en Swift 5 y Swift 6 coexisten en el mismo binario.

// Swift 6: esto ya no compila si `MyModel` no es Sendable
func fetchData() async {
    let model = MyModel()
    Task.detached {
        model.process() // Error: capture of non-Sendable 'model'
    }
}

Mi recomendación: empieza con -strict-concurrency=complete en modo Swift 5 para ver los warnings. Corrige los targets hoja primero (utilidades, networking, modelos), y luego ve subiendo. No intentes migrar todo de golpe — he visto codebases donde activar strict concurrency genera cientos de errores. Hay que ir módulo a módulo.

Más allá de la concurrencia, Swift 6 trae:

  • Typed throws (SE-0413): declaras el tipo de error con throws(ParseError). Se acabó hacer cast de Error en cada catch.
  • Noncopyable types en genéricos (SE-0427): Optional, Result y UnsafeBufferPointer aceptan tipos ~Copyable.
  • Nueva librería Synchronization: Atomic<Value> para operaciones lock-free y Mutex<Value> para exclusión mutua síncrona. Usables sin contexto async.
  • Int128 / UInt128: enteros de 128 bits nativos.
  • count(where:): por fin un método directo para contar elementos que cumplen una condición.
  • Access-level imports: internal import, private import para controlar la visibilidad de dependencias.

Apple Intelligence: la IA llega al sistema operativo

Apple presenta Apple Intelligence, su sistema de IA generativa que corre on-device en chips A17 Pro y M1+, con un backend llamado Private Cloud Compute — servidores con Apple Silicon donde los datos nunca se almacenan, nunca son accesibles para Apple, y cuyo software debe estar públicamente registrado para verificación independiente.

Para developers, la integración es en gran parte automática:

Writing Tools (reescribir, corregir, resumir) aparecen en cualquier UITextView o NSTextView estándar sin escribir código. Un nuevo delegate API da control granular (pausar sync mientras Writing Tools está activo, por ejemplo).

Genmoji introduce NSAdaptiveImageGlyph, un nuevo tipo para emojis generados por IA que se renderizan inline en texto rico.

Pero la historia profunda es que App Intents se convierte en el puente hacia Apple Intelligence. Apple ha introducido 12 nuevos dominios de App Intents — Books, Browsers, Camera, Mail, Photos, Presentations, Spreadsheets y más — cubriendo más de 100 acciones nuevas que los modelos de lenguaje de Siri entienden nativamente. Defines assistant schemas describiendo las acciones de tu app, y Apple Intelligence puede invocarlas por lenguaje natural.

Siri tiene nuevo diseño visual (borde luminoso en lugar de la esfera), conciencia de lo que hay en pantalla, acciones cross-app, Type to Siri, y un fallback a ChatGPT para preguntas que exceden sus capacidades on-device.

Para apps enterprise: si no has adoptado App Intents, ahora es el momento. Es la puerta de entrada a toda la capa de inteligencia del sistema.

SwiftUI: MeshGradient, contenedores custom y zoom transitions

SwiftUI recibe su actualización más sustancial hasta la fecha. Cambio importante: App, Scene y View están ahora aislados en @MainActor por defecto, alineándose con el modelo de concurrencia de Swift 6.

MeshGradient es una nueva vista que renderiza gradientes bidimensionales definidos por una rejilla de posiciones y colores. Completamente animable, perfecto para fondos dinámicos:

MeshGradient(
    width: 3, height: 3,
    points: [
        .init(0, 0), .init(0.5, 0), .init(1, 0),
        .init(0, 0.5), .init(0.5, 0.5), .init(1, 0.5),
        .init(0, 1), .init(0.5, 1), .init(1, 1)
    ],
    colors: [
        .red, .orange, .yellow,
        .green, .blue, .indigo,
        .purple, .pink, .white
    ]
)

El macro @Entry colapsa las ~10 líneas de boilerplate de EnvironmentKey en una sola: @Entry var itemsPerPage: Int = 10. En un proyecto con 20+ environment values, es una limpieza significativa.

La nueva API de contenedores custom (Group(subviewsOf:), ForEach(subviewOf:)) permite construir vistas contenedoras con la misma potencia que List o TabView, iterando sobre proxies Subview y SubviewsCollection. Esto es infraestructura que antes requería hacks con _VariadicView.

Zoom transitions en navegación: .navigationTransition(.zoom(sourceID:in:)) con .matchedTransitionSource produce animaciones hero fluidas en NavigationStack. El nuevo tipo Tab y .tabViewStyle(.sidebarAdaptable) habilitan la barra de tabs flotante de iPadOS 18 que se transforma en sidebar.

ScrollView gana ScrollPosition para leer offsets exactos, onScrollGeometryChange para reaccionar a cambios de contenido, y onScrollVisibilityChange para detección de visibilidad. @Previewable permite usar @State directamente en bloques #Preview.

Swift Testing: el sucesor de XCTest

Apple lanza Swift Testing, un nuevo framework de testing open-source que redefine cómo escribimos tests. Es el mayor cambio en testing de Apple desde la introducción de XCTest.

import Testing

@Suite("Autenticación")
struct AuthTests {
    @Test("Login con credenciales válidas")
    func loginSuccess() async throws {
        let result = try await AuthService.login(
            email: "test@example.com",
            password: "valid"
        )
        #expect(result.isAuthenticated)
        #expect(result.token != nil)
    }

    @Test("Login con credenciales inválidas",
          arguments: ["", "wrong", "expired"])
    func loginFailure(password: String) async throws {
        await #expect(throws: AuthError.self) {
            try await AuthService.login(
                email: "test@example.com",
                password: password
            )
        }
    }
}

Las diferencias clave con XCTest:

  • @Test marca cualquier función como test (no necesita prefijo test ni heredar de XCTestCase).
  • #expect reemplaza todas las variantes de XCTAssert* con un solo macro que captura código fuente y sub-valores en caso de fallo.
  • #require detiene el test temprano si falla (reemplaza XCTUnwrap).
  • Tests parametrizados: la misma función corre con múltiples inputs, cada uno como caso independiente.
  • Traits: .tags(), .enabled(if:), .timeLimit(), .serialized para personalizar comportamiento.
  • Ejecución paralela por defecto usando Swift concurrency.

Swift Testing coexiste con XCTest en el mismo target — puedes migrar test a test. Limitación actual: no soporta tests de rendimiento ni UI tests (siguen requiriendo XCTest).

Mi opinión: la ergonomía es vastamente superior a XCTest. El macro #expect con captura de expresiones es brillante — en un fallo ves exactamente qué valor tenía cada lado de la comparación, sin necesidad de mensajes custom. Para tests nuevos, no hay razón para seguir usando XCTest.

Xcode 16: code completion on-device y módulos explícitos

Predictive code completion es la feature estrella: un modelo de ML entrenado específicamente para Swift y los SDKs de Apple, que corre enteramente en local en Apple Silicon. Sin cloud, sin enviar código a ningún sitio. Para equipos enterprise con código propietario, esto es fundamental — tienes autocompletado inteligente sin comprometer la confidencialidad.

El build system introduce Explicitly Built Modules, que divide la compilación en tres fases: escaneo de dependencias, compilación de módulos y compilación de fuentes. Mejora el paralelismo, los diagnósticos y la velocidad del debugger (LLDB reutiliza los módulos compilados). Activo por defecto para C/Objective-C, opt-in para Swift.

DWARF5 es el formato de símbolos de debug por defecto, produciendo dSYMs más pequeños. Nuevo Flame Graph en Instruments para visualizar tiempo de ejecución. El Thread Performance Checker ahora detecta escrituras excesivas a disco y diagnósticos de arranque lento. Y la resolución de paquetes SPM ya no bloquea el build.

SwiftData año 2: custom stores e historial de cambios

SwiftData aborda gaps arquitectónicos en su segundo año:

El protocolo DataStore desacopla SwiftData de la capa de almacenamiento de Core Data. Puedes implementar backends de persistencia custom (JSON, variantes de SQLite, almacenamiento cloud) manteniendo @Model, @Query y ModelContext funcionando igual. Esto cambia completamente la propuesta de valor de SwiftData: ya no es solo "Core Data con macros", es un framework de persistencia extensible.

#Unique define restricciones de unicidad compuestas con upsert automático. #Index crea índices simples o compuestos para rendimiento de queries. Una nueva History API rastrea cambios del modelo a lo largo del tiempo mediante transacciones, cambios y tokens — esencial para sync con servidor, actualización de widgets, y manejo de cambios out-of-process.

UIKit: UIUpdateLink, automatic trait tracking y animaciones unificadas

UIUpdateLink reemplaza CADisplayLink con tracking automático de vistas, modo de baja latencia para apps de dibujo, y mejor eficiencia de batería. Automatic trait tracking elimina la necesidad de llamar manualmente a registerForTraitChanges — UIKit detecta qué traits usas en layoutSubviews, drawRect y updateConstraints, e invalida automáticamente cuando cambian.

Gran novedad de interop: los tipos Animation de SwiftUI pueden ahora animar vistas UIKitUIView.animate(.spring) { ... } funciona directamente. Los sistemas de gestos se unifican con UIGestureRecognizerRepresentable, que permite que gesture recognizers de UIKit participen en jerarquías SwiftUI.

Nuevos frameworks y APIs destacadas

  • Controls API: widgets de terceros en el Control Center, Lock Screen y botón de Acción. Construidos sobre App Intents. Visibilidad de tu app fuera de la app.
  • AccessorySetupKit: simplifica el pairing Bluetooth/Wi-Fi a un solo tap, sin permisos amplios de red.
  • Translation: acceso programático a los modelos de traducción de Apple vía TranslationSession.
  • Core ML: MLTensor para operaciones multidimensionales, modelos stateful para LLMs, y compresión de pesos a 4 bits.
  • Vision framework: rediseño completo con API Swift nativa y async/await.
  • visionOS 2: redimensionado de volúmenes, APIs enterprise, tracking de habitaciones y objetos.
  • watchOS 11: Live Activities automáticas en Apple Watch, Double Tap API expandido, widgets interactivos.
  • macOS 15 Sequoia: iPhone Mirroring, Game Porting Toolkit 2.

Privacidad: apps bloqueadas y passkeys automáticos

iOS 18 introduce apps bloqueadas y ocultas a nivel del sistema — el usuario puede bloquear cualquier app con Face ID/Touch ID sin trabajo del developer. Acceso limitado a contactos muestra un picker del sistema para seleccionar contactos específicos. Y automatic passkey upgrades transicionan cuentas basadas en contraseña a passkeys de forma transparente.

Conclusión: qué hacer ahora

La WWDC 2024 cierra un ciclo y abre otro. Swift 6 es la culminación de cuatro años de trabajo en concurrencia segura. Apple Intelligence redefine la relación entre apps y el sistema. Y Swift Testing moderniza la forma en que verificamos nuestro código.

Si tuviera que elegir tres acciones concretas para un equipo iOS enterprise:

  1. Activa -strict-concurrency=complete en modo Swift 5 hoy. Empieza a ver los warnings, entiende los patrones, y corrige módulo a módulo. Es la tarea más grande y la más urgente.
  2. Implementa App Intents en tus flujos principales. Con Apple Intelligence, App Intents pasa de ser "nice to have" a ser la puerta de entrada de tu app al sistema.
  3. Usa Swift Testing para todos los tests nuevos. No migres XCTest existente todavía, pero cada test que escribas a partir de ahora debería usar @Test y #expect.

Ha sido una WWDC brutal. Swift 6, Apple Intelligence, Swift Testing — cada uno de estos cambios por separado justificaría un artículo completo. Juntos, redefinen lo que significa desarrollar para iOS. Toca arremangarse.

¿Necesitas ayuda con la migración?

💡 ¿Tienes un proyecto que necesita migración? Podemos ayudarte a hacer la transición de forma eficiente y sin interrupciones en tu flujo de desarrollo.

📩 Contáctanos aquí para más información.

Share:
Sobre el autor
Francisco José García Navarro

Francisco José García Navarro

Francisco José García Navarro es el cofundador y CEO de AtalayaSoft e ingeniero de software iOS experimentado con más de 25 años en desarrollo de software. Especializado en aplicaciones iOS nativas, Francisco tiene una amplia trayectoria trabajando con clientes de alto perfil como Banco Santander, Fox International Channel, Repsol y National Geographic.