iOS 27 ya está aquí: Siri con Gemini, App Intents obligatorio y lo que cambia de verdad para developers

iOS 27 lleva cuatro días en la calle. Salió el 14 de septiembre de 2026 y, a diferencia de lo que suelen contar los artículos sobre "el futuro del desarrollo iOS", aquí no hace falta especular: ya se puede instalar, ya hay apps en la App Store adaptadas y ya hay desarrolladores peleándose con los cambios en producción. Así que en vez de imaginar cómo será programar para iPhone en 2030, vamos a lo concreto: qué ha cambiado de verdad con esta versión y con Swift 6.2, y qué toca hacer ya con el código.

Siri se reconstruye con un modelo de Google por debajo

El titular más comentado de este ciclo es que la nueva Siri de iOS 27 funciona sobre un modelo de Gemini de Google, adaptado a medida para Apple. No es un rumor: Apple ha licenciado un modelo de aproximadamente 1,2 billones de parámetros por un acuerdo que ronda los mil millones de dólares al año, según ha confirmado el propio blog de Google. El resultado es una Siri capaz de entender peticiones en lenguaje natural bastante más complejas y de ejecutar acciones dentro de las apps de terceros, no solo dentro de las suyas propias.

Para quien programa, el dato importante no es de dónde saca Apple el modelo, sino cómo se conecta esa Siri con tu app. Y ahí es donde entra el cambio que de verdad obliga a moverse.

App Intents deja de ser una opción

Apple ha dado por muerto SiriKit en WWDC 2026: sigue funcionando, mostrará avisos de compilación deprecados y en algún momento dejará de hacerlo. La nueva Siri solo llama a las apps a través de App Intents. Si tu app no expone sus acciones mediante ese framework, para la nueva Siri es como si no existiera.

App Intents 2.0 trae, además, piezas que no estaban antes: tipos de entidad más ricos, respuestas en streaming para acciones que tardan en completarse, conversaciones de varios turnos con seguimiento de contexto y una API de anotaciones de vista que permite al usuario referirse a elementos concretos de la interfaz al hablar con Siri («resérvame esto», señalando una tarjeta en pantalla).

Un intent mínimo pero completo para iOS 27 se ve así:

import AppIntents

struct BuscarPedidoIntent: AppIntent {
    static var title: LocalizedStringResource = "Buscar pedido"
    static var description = IntentDescription("Consulta el estado de un pedido por su número")

    @Parameter(title: "Número de pedido")
    var numeroPedido: String

    // Streaming: Siri puede mostrar resultados parciales mientras se resuelve
    func perform() async throws -> some IntentResult & ProvidesDialog {
        let pedido = try await PedidosService.shared.buscar(numeroPedido)
        let dialogo = "Tu pedido (numeroPedido) está (pedido.estado)."
        return .result(dialog: IntentDialog(stringLiteral: dialogo))
    }
}

struct PedidosShortcuts: AppShortcutsProvider {
    static var appShortcuts: [AppShortcut] {
        AppShortcut(
            intent: BuscarPedidoIntent(),
            phrases: ["Busca mi pedido en (.applicationName)"],
            shortTitle: "Buscar pedido",
            systemImageName: "shippingbox"
        )
    }
}

Si tu app todavía depende solo de SiriKit, esto es lo primero que hay que planificar antes de que termine el año. No hace falta migrarlo todo de golpe, pero cada acción relevante de cara al usuario necesita, tarde o temprano, su propio AppIntent.

Foundation Models ya no es solo el modelo de Apple

Este es, para mí, el cambio técnico más interesante de los dos últimos WWDC. Hasta la versión anterior, el framework Foundation Models solo daba acceso al modelo propio de Apple, de unos 3.000 millones de parámetros, corriendo en el dispositivo. Con iOS 27 eso cambia: aparece un protocolo público, LanguageModel, que cualquier proveedor puede implementar. En la práctica, puedes cambiar entre el modelo on-device de Apple, un modelo en Private Cloud Compute, Gemini o Claude cambiando muy poco código, porque la interfaz es la misma.

El framework mantiene lo que ya funcionaba bien: la generación guiada con el macro @Generable, que te permite pedirle al modelo una respuesta directamente tipada como una estructura Swift, en vez de parsear texto libre.

import FoundationModels

@Generable
struct ResumenTicket {
    @Guide(description: "Título corto del problema, máximo 8 palabras")
    let titulo: String

    @Guide(description: "Prioridad estimada", .anyOf(["baja", "media", "alta", "urgente"]))
    let prioridad: String

    @Guide(description: "Pasos siguientes recomendados, de 2 a 4 puntos")
    let siguientesPasos: [String]
}

let sesion = LanguageModelSession()
let entrada = "El usuario dice que la app se cierra sola al abrir la cámara desde el chat, le pasa desde ayer y en varios modelos de iPhone."

let respuesta = try await sesion.respond(
    to: entrada,
    generating: ResumenTicket.self
)

print(respuesta.content.titulo)
print(respuesta.content.prioridad)

Además, desde iOS 27 el modelo on-device acepta imágenes junto al texto, así que se pueden resolver tareas visuales sencillas sin salir del dispositivo ni depender de una llamada a un servidor. Y hay un detalle nada menor para quien tiene una app pequeña: los desarrolladores dentro del programa de pequeñas empresas de la App Store, con menos de dos millones de descargas totales, pueden usar los modelos de Apple en Private Cloud Compute sin coste de API.

Liquid Glass, un año después: menos moda, más ajustes por queja de usuarios

Liquid Glass se presentó en WWDC 2025 como el rediseño más grande desde iOS 7. Un año de uso real ha dejado bastante crítica de fondo: problemas de contraste, elementos difíciles de leer sobre ciertos fondos y quejas de accesibilidad. Apple ha respondido en WWDC 2026 con ajustes concretos en iOS 27, entre ellos un control de intensidad que permite reducir el efecto de transparencia, y la vuelta de la búsqueda a la barra de pestañas tras las críticas por haberla escondido.

Para quien programa, sigue siendo válido lo esencial: si tu app usa los controles estándar de SwiftUI o UIKit, el material llega solo, sin tocar código. Si tienes UI personalizada, el modificador se aplica dentro de un contenedor específico para que varios elementos de cristal compartan la misma fuente de luz y no se vean como piezas sueltas:

struct ContentCard: View {
    let titulo: String
    let cuerpo: String

    var body: some View {
        GlassEffectContainer {
            VStack(alignment: .leading, spacing: 10) {
                Text(titulo)
                    .font(.headline)
                Text(cuerpo)
                    .font(.subheadline)
                    .foregroundStyle(.secondary)
            }
            .padding(20)
            .frame(maxWidth: .infinity, alignment: .leading)
            .glassEffect(.regular, in: RoundedRectangle(cornerRadius: 24, style: .continuous))
        }
    }
}

La recomendación práctica, después de un año de feedback real, es no forzar el cristal en zonas de mucho texto o alto contraste (listados largos, pantallas de lectura) y dejarlo para elementos flotantes: barras, controles, tarjetas de acción. Ahí es donde el material se ve bien y no penaliza la legibilidad.

Swift 6.2: el cambio silencioso que afecta a cada proyecto nuevo

Mientras Siri y Liquid Glass se llevan los titulares, Swift 6.2 ha cambiado algo que afecta a todos los proyectos nuevos que se crean desde Xcode 26: el aislamiento de actor por defecto. Antes, el código sin anotar corría sin aislamiento explícito (nonisolated). Ahora, un proyecto nuevo aplica @MainActor por defecto a todo lo que no marques lo contrario, lo que en la práctica hace que tu app arranque siendo de un solo hilo salvo que digas explícitamente qué código quieres sacar de ahí.

Esto se controla en los ajustes de compilación, en Default Actor Isolation, con dos valores posibles: MainActor o nonisolated. Los proyectos existentes que actualizas a Xcode 26 mantienen nonisolated por defecto, así que el cambio no te salta encima sin avisar, pero conviene decidir conscientemente cuál quieres en cada proyecto en vez de dejarlo al azar.

Otra pieza que trae Swift 6.2 es nonisolated(nonsending): una función síncrona marcada como nonisolated ya no salta automáticamente al executor global, sino que hereda el aislamiento de quien la llama. Es un ajuste pequeño sobre el papel, pero evita una categoría entera de bugs de concurrencia que antes aparecían por sorpresa al llamar código «neutro» desde un actor concreto.

Xcode 26 trae herramientas de migración para ayudar con este cambio, pero conviene revisarlo fichero a fichero, no de forma automática y ciega, sobre todo en la capa de red y en cualquier sitio con estado compartido.

Lo que toca hacer antes de que acabe 2026

  • Revisa qué acciones de tu app tiene sentido exponer como AppIntent y empieza por las dos o tres más usadas, no por todas a la vez.
  • Si usas Foundation Models, valora si te interesa el nuevo protocolo LanguageModel para no quedar atado solo al modelo on-device de Apple.
  • Audita tu UI personalizada con Liquid Glass: quita el cristal de las zonas de lectura densa y déjalo en elementos flotantes.
  • Decide explícitamente el valor de Default Actor Isolation en cada proyecto, en vez de dejar el que trae Xcode por defecto sin mirarlo.
  • Si tu app es pequeña y está en el programa de pequeñas empresas de la App Store, revisa las condiciones de acceso gratuito a los modelos de Apple en Private Cloud Compute: puede ahorrarte factura de IA.

Nada de esto es ciencia ficción a cinco años vista. Es lo que ya corre en el iPhone de cualquiera que haya actualizado esta semana, y lo que va a decidir, muy pronto, si tu app aparece cuando alguien le pide algo a Siri o si se queda fuera del mapa.

Imagen: Pexels / AS Photography

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP