← Todos los articulos

App Intents en iOS 27: segundo plano, sincronización y Spotlight

App Intents llegó en iOS 16 como el API de acciones tipadas y estructuradas de Apple para Shortcuts, Siri y Spotlight; iOS 17 lo extendió a widgets impulsados por App Intents; iOS 18 lo convirtió en el contrato para la superficie de acciones de Apple Intelligence; iOS 26 lo llevó a Visual Intelligence y a los snippets interactivos. iOS 27 vuelve a cambiar la forma de la apuesta, y el cambio es mecánico, no cosmético: ahora un intent puede ejecutarse más allá del límite de 30 segundos en segundo plano, una entidad puede portar una identidad que sobrevive al viaje entre los dispositivos de un usuario, y una consulta puede reparar su propio índice de Spotlight cuando el sistema se lo pide. iOS 27 suma capacidad, no azúcar sintáctica.1

Cada versión anterior amplió quién podía invocar tus intents. iOS 27 amplía qué pueden hacer tus intents una vez invocados. Un intent de sincronización que opera sobre unos pocos miles de registros antes competía contra un temporizador de 30 segundos y perdía; ahora le pide al sistema más margen de pista e informa su avance mientras trabaja. Una entidad que significaba una cosa en el iPhone y otra distinta en la Mac ahora se resuelve al mismo objeto en ambos. Este artículo recorre la superficie de iOS 27 contrastándola con la documentación de Apple, con el mismo enfoque que el resto del clúster: qué agrega una app que ya distribuye App Intents para ganar cada nueva capacidad.

TL;DR

  • LongRunningIntent extiende el tiempo de ejecución en segundo plano de un intent más allá del límite de 30 segundos del sistema. Envuelves el trabajo en performBackgroundTask(options:operation:) y pasas LongRunningTaskOptions; el protocolo refina ProgressReportingIntent, así que informar el avance es un requisito, no una opción. Las Live Activities renderizan ese avance automáticamente.234
  • SyncableEntity declara que un AppEntity porta un identificador consistente entre los dispositivos de un usuario, lo que permite al sistema referirse al mismo objeto en iPhone, Mac y Watch (Siri lo usa para pasar una conversación de un dispositivo a otro).5
  • IndexedEntityQuery añade soporte de reindexación en Spotlight a un EntityQuery, de modo que cuando el sistema detecta un problema con el índice de tu app puede pedirle a tu consulta que vuelva a donar las entidades afectadas.6
  • AppUnionValue y AppUnionValueCasesProviding (generados por la macro @UnionValue) permiten que un único parámetro acepte varios tipos de entidad distintos, con una interfaz de selección y resúmenes de parámetros adecuados.78
  • OwnershipProvidingEntity, EntityOwnership y EntityCollection cubren la confirmación consciente de la propiedad y la eficiencia en operaciones masivas; RunSystemShortcutIntent e IntentExecutionTargets cubren las acciones del sistema lanzadas desde un widget y qué proceso ejecuta un intent.910111213

El muro de los 30 segundos: LongRunningIntent

El límite de ejecución en segundo plano ha sido el techo silencioso de lo que un App Intent podía hacer. Cuando el sistema ejecuta un intent en segundo plano (el usuario le pide a Siri que sincronice, luego bloquea el teléfono y se lo guarda en el bolsillo), tradicionalmente le concede alrededor de 30 segundos para terminar.2 Para registrar un vaso de agua eso es generoso. Para sincronizar una biblioteca, ejecutar inferencia en el dispositivo o procesar un archivo grande, 30 segundos son una guillotina: el sistema mata la tarea a mitad de escritura y el usuario obtiene un resultado a medias.

iOS 27 introduce LongRunningIntent, un protocolo que un intent adopta para pedirle al sistema una ventana de segundo plano extendida.2 Apple nombra los casos de uso directamente en la documentación: operaciones con archivos, sincronización de datos, inferencia de machine learning y procesamiento de datos sobre un conjunto suficientemente grande. La declaración te dice la restricción más importante antes de que escribas una sola línea:

protocol LongRunningIntent : ProgressReportingIntent

LongRunningIntent refina ProgressReportingIntent.2 No puedes adoptar el protocolo de larga duración sin informar también el avance, por diseño. El tiempo de ejecución extendido es un privilegio que el sistema concede de forma condicional, y la condición es que sigas diciéndole hasta dónde has llegado. Deja de informar y el sistema puede revocar la extensión y terminar la tarea antes de tiempo.3

El trabajo va dentro de performBackgroundTask(options:operation:):

@discardableResult
func performBackgroundTask<T>(
    options: LongRunningTaskOptions = [],
    operation: @escaping () async throws -> T
) async throws -> T

Llamas al método desde el cuerpo de perform() de tu intent y colocas el código costoso en el closure operation. El método extiende automáticamente tu tiempo de ejecución más allá del límite estándar de 30 segundos en las plataformas que lo imponen; no inicias una tarea de segundo plano aparte ni gestionas un UIBackgroundTaskIdentifier por tu cuenta.3 Un intent de sincronización de biblioteca se ve así:

import AppIntents

struct SyncLibraryIntent: LongRunningIntent {
    static var title: LocalizedStringResource = "Sync Library"

    func perform() async throws -> some IntentResult {
        try await performBackgroundTask(options: []) {
            let records = try await server.fetchPendingRecords()
            for (offset, record) in records.enumerated() {
                try await store.apply(record)
                progress.completedUnitCount = Int64(offset + 1)
                progress.totalUnitCount = Int64(records.count)
            }
            return ()
        }
        return .result()
    }
}

Dos cosas merecen una explicación, porque los tutoriales las omiten.

La propiedad progress es el contrato, no telemetría. Apple es explícito: mientras tu operación se ejecuta, actualiza el Progress de la conformidad con ProgressReportingIntent de forma regular, y si no lo haces, el sistema puede cancelar la extensión del tiempo de ejecución y terminar tu tarea prematuramente.3 Informar el avance en un intent normal es un detalle agradable. En un LongRunningIntent es el latido que mantiene viva la extensión.

LongRunningTaskOptions declara los requisitos de recursos. El valor de opciones (un struct de estilo OptionSet que por defecto es []) le informa al sistema sobre necesidades de recursos adicionales para la tarea, que tiene en cuenta al calcular el tiempo de ejecución que concede.4 Un conjunto vacío es el caso común. Recurres a opciones explícitas cuando el trabajo necesita más que el perfil por defecto.

La recompensa, más allá de sobrevivir pasados los 30 segundos: las Live Activities renderizan el avance gratis. La documentación indica que las Live Activities muestran el avance de la tarea del intent usando información que reciben automáticamente de performBackgroundTask, dibujando el título, el subtítulo y una barra de progreso a partir de los valores que tu código informa.3 Una sincronización larga iniciada por voz aparece en la pantalla de bloqueo como una barra de progreso en vivo sin que construyas una sola vista de Live Activity para ella. El intent informa, el sistema renderiza.

Watch on Apple Developer ↗
Apple demuestra un intent de carga de fotos que sobrevive más allá del límite de 30 segundos mediante LongRunningIntent, con un botón de detener en la Live Activity para que una persona pueda cancelarlo en cualquier momento.

En la sesión 345, Apple demuestra LongRunningIntent frente a un caso de falla real, una carga de fotos que se moría una y otra vez dentro de la ventana de 30 segundos, y muestra al sistema gestionando el ciclo de vida de la tarea en segundo plano mientras expone el avance y un control de cancelación como Live Activity.14

Identidad consistente: SyncableEntity

Un AppEntity tiene un id. En un solo dispositivo ese identificador solo tiene que ser único dentro de la app. El problema empieza en el momento en que un usuario posee más de un dispositivo, que en el ecosistema de Apple es lo predeterminado. El “Proyecto Atlas” que el usuario conversó con Siri en su iPhone tiene que ser reconociblemente el mismo “Proyecto Atlas” cuando retoma la conversación en la Mac. Si el identificador local del iPhone difiere del de la Mac, el sistema tiene dos objetos sin relación y ninguna forma de conectarlos.

SyncableEntity es la respuesta de iOS 27:5

protocol SyncableEntity : AppEntity

Adoptarlo declara que el identificador de tu entidad es el mismo en todos los dispositivos. La presencia del protocolo le indica al sistema que puede referirse a tu entidad de forma consistente de un dispositivo a otro. Apple da la recompensa concreta: Siri usa la capacidad para transferir una conversación de un dispositivo a otro.5

El costo de adopción depende por completo de dónde provienen tus identificadores. Si tus entidades ya usan un identificador estable entre dispositivos (un UUID emitido por el servidor, el nombre de un registro de iCloud), adoptas SyncableEntity sin ningún otro cambio, porque el valor que ya almacenas es el valor que el sistema necesita.5

import AppIntents

struct ProjectEntity: SyncableEntity {
    static var typeDisplayRepresentation: TypeDisplayRepresentation = "Project"
    static var defaultQuery = ProjectQuery()

    // A UUID issued by the backend and identical on every device.
    var id: UUID

    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(title: "\(name)")
    }

    @Property(title: "Name") var name: String
}

La trampa es la app que acuña un identificador local nuevo en cada dispositivo (un id de fila autoincremental, un UUID por instalación). Esos identificadores son únicos localmente y carecen de sentido entre dispositivos. La recomendación de Apple para ese caso: adopta el protocolo y ancla tu identidad en el valor que sí es estable, para que el sistema tenga algo duradero en lo cual apoyarse.5 La sincronización era el problema difícil que los equipos seguían resolviendo a mano con su propia plomería de iCloud. SyncableEntity traslada la declaración de identidad entre dispositivos al framework, donde Siri y el resto del sistema pueden actuar sobre ella.

Búsqueda que se autorrepara: IndexedEntityQuery

iOS 16 te permitía donar instancias de IndexedEntity a Spotlight para que las entidades individuales se volvieran buscables. La brecha era la reparación. Los índices se desfasan, se corrompen o se quedan atrás tras una migración, y hasta iOS 27 el único recurso del sistema era apoyarse en el delegado CSSearchableIndex de tu app o en su CSImportExtension.

IndexedEntityQuery cierra la brecha al permitir que el sistema le pida a tu consulta que reindexe:6

protocol IndexedEntityQuery : EntityQuery where Self.Entity : IndexedEntity

La cláusula where es la condición previa: la entidad de la consulta tiene que conformar a IndexedEntity, porque la reindexación solo tiene sentido para entidades que donas a Spotlight en primer lugar.6 Cuando el sistema topa con un problema en el índice de una app, llama a los métodos de este protocolo si tu tipo de consulta lo adopta; si tu consulta no lo hace, Spotlight sigue pidiéndole a tu objeto CSSearchableIndex (o a tu CSImportExtension, si donaste asociando la entidad con ese tipo) que haga el trabajo en su lugar.6 Implementas los métodos para obtener las entidades solicitadas y donarlas de nuevo a través de tu índice buscable preferido.

import AppIntents
import CoreSpotlight

struct PhotoQuery: IndexedEntityQuery {
    func entities(for identifiers: [Photo.ID]) async throws -> [Photo] {
        try await library.photos(matching: identifiers)
    }

    func suggestedEntities() async throws -> [Photo] {
        try await library.recentPhotos(limit: 20)
    }

    // Called by the system during reindexing. Fetch the requested
    // entities and donate them again to Spotlight.
    func entities(matching string: String) async throws -> [Photo] {
        try await library.photos(matchingText: string)
    }
}

El valor es operativo. Una app que implementa bien IndexedEntityQuery participa en el bucle de recuperación de Spotlight: el sistema nota que el índice está mal y la app suministra datos frescos bajo demanda, en lugar de que el usuario pierda silenciosamente resultados de búsqueda hasta la próxima re-donación completa. El artículo fundacional sobre App Intents del clúster cubrió la exposición de IndexedEntity a secas para hacer buscables las entradas; IndexedEntityQuery es la capa de mantenimiento que va encima.

Un parámetro, varios tipos: AppUnionValue

Muchísimos intents reales toman un parámetro que legítimamente es uno de entre varios tipos. “Compartir esto”, donde “esto” es una foto, un documento o un enlace. Los rodeos previos a iOS 27 eran feos: intents separados por tipo, o un discriminador de tipo string más parámetros opcionales que la interfaz de selección no lograba renderizar con limpieza.

iOS 27 añade AppUnionValue para parámetros de unión tipados:7

protocol AppUnionValue : TypeDisplayRepresentable

Un valor de unión que conforma al protocolo funciona como parámetro de Shortcuts con metadatos ricos, de modo que el sistema puede presentar un selector apropiado y un resumen de parámetro sensato a través de los tipos miembros.7 No escribes la conformidad a mano. La macro @UnionValue la genera, y esa misma macro genera un enum anidado Cases que conforma a AppUnionValueCasesProviding:78

protocol AppUnionValueCasesProviding : AppEnum

AppUnionValueCasesProviding lo conforma automáticamente el enum Cases que la macro emite.8 Vincula el enum de casos de vuelta con el tipo del valor de unión y hereda metadatos a través de su conformidad con AppEnum, que es lo que le da a cada caso su nombre visible en el selector.8 En la práctica escribes la unión y la anotas:

import AppIntents

@UnionValue
enum ShareTarget {
    case photo(PhotoEntity)
    case document(DocumentEntity)
    case link(URL)
}

struct ShareIntent: AppIntent {
    static var title: LocalizedStringResource = "Share Item"

    @Parameter(title: "Item")
    var target: ShareTarget

    func perform() async throws -> some IntentResult {
        // Switch over the concrete case and act accordingly.
        return .result()
    }
}

La macro @UnionValue se encarga de las conformidades con AppUnionValue y AppUnionValueCasesProviding; si quieres metadatos personalizados más allá de los predeterminados, implementas los requisitos del protocolo en una extensión.7 Un parámetro, tres tipos válidos, un selector que sabe cómo mostrar los tres.

Propiedad y eficiencia

Dos preocupaciones distintas de iOS 27 comparten esta sección porque ambas protegen al sistema de actuar con descuido sobre tus datos: la confirmación consciente de la propiedad y la eficiencia en operaciones masivas.

Confirmar acciones destructivas: OwnershipProvidingEntity

Cuando tu app pasa entidades a los intents y las devuelve como resultados, Apple Intelligence, Siri y los atajos personalizados pueden actuar sobre esas entidades entre apps. Para acciones destructivas o sensibles (eliminar una entidad, actualizar una compartida) quieres una confirmación que cargue con el contexto correcto. OwnershipProvidingEntity lo aporta:9

protocol OwnershipProvidingEntity : AppEntity

Conforma tu entidad a él y el sistema pide confirmación, con el contexto apropiado en el diálogo, cuando un intent actúa sobre entidades compartidas o de acceso público.9 El estado de propiedad en sí es un valor EntityOwnership, un struct basado en flags donde especificas un único estado o combinas varios con un OptionSet:10

import AppIntents

struct AlbumEntity: OwnershipProvidingEntity {
    static var typeDisplayRepresentation: TypeDisplayRepresentation = "Album"
    static var defaultQuery = AlbumQuery()

    var id: UUID
    var isSharedWithFamily: Bool
    var isPublished: Bool

    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(title: "\(name)")
    }

    @Property(title: "Name") var name: String

    // Reflect how the user has shared this album so the system can
    // calibrate its confirmation dialog.
    var ownership: EntityOwnership {
        var state: EntityOwnership = []
        if isSharedWithFamily || isPublished {
            state = .shared
        }
        return state
    }
}

El mecanismo importa sobre todo para apps con contenido compartido: un álbum de fotos que publicaste o compartiste con tu familia debería producir una confirmación más cautelosa que uno privado, y OwnershipProvidingEntity es la forma en que la entidad le dice al sistema cuál es cuál.9

Operaciones masivas sin el golpe de memoria: EntityCollection

Resolver entidades no es gratis. Cuando un intent toma cientos de entidades como parámetro, obligar al sistema a resolver cada identificador en una instancia completa durante la resolución de parámetros puede costar tiempo y memoria significativos en un mal momento. EntityCollection es el arreglo:11

struct EntityCollection<Entity> where Entity : AppEntity

La colección almacena inicialmente solo el identificador de cada entidad y ofrece la opción de obtener las instancias completas después, si las necesitas.11 Úsala como tipo de variable cuando guardas muchos identificadores, y úsala como tipo de parámetro cuando un intent opera sobre un conjunto grande:

import AppIntents

struct DisableNotificationsIntent: AppIntent {
    static var title: LocalizedStringResource = "Disable Notifications"

    // Hundreds of conversations resolve lazily, not all at once.
    @Parameter(title: "Conversations")
    var conversations: EntityCollection<ConversationEntity>

    func perform() async throws -> some IntentResult {
        return .result()
    }
}

Para un parámetro que contiene cientos de entidades, omitir la resolución por identificador ahorra tiempo y memoria justo cuando el usuario está esperando a que la acción comience.11

Dónde se ejecuta el intent: RunSystemShortcutIntent e IntentExecutionTargets

Dos adiciones más pequeñas de iOS 27 completan la superficie. RunSystemShortcutIntent es un intent exclusivo de widgets para lanzar otra app o ejecutar un App Shortcut, un atajo personalizado o una acción del sistema desde el botón de un widget:12

struct RunSystemShortcutIntent

Lo usas únicamente para inicializar un Button con el inicializador de atajo del sistema y colocar ese botón en un widget; no hace nada útil fuera de ese contexto.12 Cuando el usuario configura el widget elige la acción del botón, y el intent suministra los metadatos que el sistema necesita para la interfaz de configuración. No le da a tu widget acceso a las acciones, parámetros o implementación de un atajo. Si el atajo elegido necesita pedir alguna entrada, el sistema puede abrir la app Shortcuts para ejecutarla.12

IntentExecutionTargets responde una pregunta que surge en cuanto compartes intents y entidades entre tu app, tu extensión de widget y tu extensión de App Intents a través de un paquete o framework de Swift: ¿qué proceso ejecuta el intent?13

struct IntentExecutionTargets

Por defecto, el sistema ejecuta un intent o una consulta de entidad usando cualquier destino disponible.13 Usas IntentExecutionTargets para acotar eso. El ejemplo de Apple es un navegador: agregar un marcador puede ocurrir mientras la app no está visible, así que la extensión de App Intents está bien, pero abrir una pestaña nueva solo tiene sentido cuando la app está visible, lo que requiere el propio proceso de la app.13 Declaras los destinos válidos y el sistema respeta la restricción.

Ruta de adopción

Una app que ya distribuye App Intents agrega las capacidades de iOS 27 de forma incremental; ninguna reescribe el modelo central.

  1. Encuentra tu intent más lento. Cualquier intent que haga I/O de archivos, sincronización, inferencia en el dispositivo o procesamiento de datos grandes es candidato a LongRunningIntent. Adopta el protocolo, mueve el trabajo a performBackgroundTask(options:operation:) e informa el progress de principio a fin. Obtienes tiempo de ejecución más allá de los 30 segundos y avance gratis en las Live Activities.23
  2. Audita los identificadores de tus entidades. Si ya son estables entre dispositivos (UUID de servidor, nombre de registro de iCloud), conforma las entidades relevantes a SyncableEntity y publica. Si son por dispositivo, arregla primero la identidad y luego conforma.5
  3. Añade IndexedEntityQuery a las consultas cuyas entidades sean IndexedEntity. Es puramente aditivo: los métodos solo se invocan cuando el sistema necesita una reindexación, y tus resultados de búsqueda se mantienen correctos a pesar del desfase del índice.6
  4. Colapsa los parámetros multitipo con @UnionValue. Donde sea que hayas simulado una unión con intents separados o un string discriminador, la macro te da un único parámetro limpio.7
  5. Marca las entidades compartidas con OwnershipProvidingEntity, y cambia los parámetros de conjunto grande a EntityCollection. Lo primero mejora la seguridad de la confirmación, lo segundo mejora el rendimiento de la resolución.911

Preguntas frecuentes

¿Cuánto tiempo puede ejecutarse un LongRunningIntent en segundo plano?

Apple documenta el piso que levanta, no un techo fijo. El sistema tradicionalmente le da a una tarea en segundo plano alrededor de 30 segundos para terminar, y LongRunningIntent (mediante performBackgroundTask(options:operation:)) extiende automáticamente esa ventana más allá del límite estándar en las plataformas que lo imponen.23 La extensión es condicional: tienes que seguir actualizando el Progress de la conformidad con ProgressReportingIntent, y si te detienes, el sistema puede cancelar la extensión y terminar tu tarea antes de tiempo.3 Trata el informe del avance como el precio del tiempo de ejecución extra.

¿Tengo que informar el avance para usar LongRunningIntent?

Sí. LongRunningIntent se declara como protocol LongRunningIntent : ProgressReportingIntent, así que adoptarlo requiere la conformidad con ProgressReportingIntent y su Progress.2 Más allá de satisfacer al compilador, las actualizaciones regulares del avance mantienen viva la extensión del tiempo de ejecución en segundo plano y alimentan el título, el subtítulo y la barra de progreso que las Live Activities renderizan automáticamente a partir de performBackgroundTask.3

¿Qué cambia realmente SyncableEntity en tiempo de ejecución?

Declara que el identificador de tu entidad es idéntico entre los dispositivos de un usuario, lo que permite al sistema tratar el objeto como una sola entidad en todas partes en lugar de objetos separados por dispositivo.5 La capacidad concreta que Apple nombra: Siri puede transferir una conversación sobre esa entidad de un dispositivo a otro. Si tus identificadores ya son estables entre dispositivos, adoptas el protocolo sin ningún otro cambio; si son por dispositivo, primero reanclas la identidad en un valor estable.5

¿Cuándo llama el sistema a IndexedEntityQuery?

Cuando encuentra un problema con el índice de Spotlight de tu app y tu tipo de consulta adopta IndexedEntityQuery (con su entidad conformando a IndexedEntity).6 El sistema llama a los métodos del protocolo para que obtengas las entidades afectadas y las dones de nuevo a Spotlight. Si tu consulta no adopta el protocolo, Spotlight recurre a pedírselo a tu objeto CSSearchableIndex, o a tu CSImportExtension si donaste a través de ese tipo.6

¿Por qué usar EntityCollection en lugar de un arreglo simple de entidades?

EntityCollection<Entity> almacena de entrada solo el identificador de cada entidad y obtiene las instancias completas después, si hace falta.11 Como parámetro de un intent, evita que el sistema fuerce la resolución de cada identificador en una instancia completa durante la resolución de parámetros, lo que para un parámetro que contiene cientos de entidades ahorra tiempo y memoria en un momento potencialmente crítico.11 Un arreglo [Entity] simple resuelve todo de forma ansiosa.

¿Se puede usar RunSystemShortcutIntent fuera de los widgets?

No. Existe únicamente para inicializar un Button con el inicializador de atajo del sistema para colocarlo en un widget, y no proporciona ninguna funcionalidad en otros contextos.12 Expone metadatos para la interfaz de configuración del widget y representa la acción elegida por el usuario; no le da a tu widget ni a tu app acceso a las acciones, parámetros o implementación del atajo subyacente.12

El clúster completo del Ecosistema Apple: App Intents tipados; las adiciones de iOS 26; la pregunta del enrutamiento frente a las herramientas MCP; Foundation Models; el nuevo control de tool-calling de Foundation Models; la distinción entre tiempo de ejecución y LLM de herramientas; tres superficies; el patrón de fuente única de verdad; servidores MCP junto a una app; Live Activities; el tiempo de ejecución de watchOS; los internos de SwiftUI; la disciplina de esquemas en SwiftData; patrones de Liquid Glass; distribución multiplataforma; la matriz de plataformas; el framework Vision; los internos de @Observable; la accesibilidad como plataforma. El hub está en la Serie del Ecosistema Apple. Para un contexto más amplio de iOS con agentes de IA, consulta la guía de Desarrollo de Agentes en iOS.

Referencias


  1. Documentación para desarrolladores de Apple: App Intents. La referencia del framework que cubre AppIntent, AppEntity, consultas, parámetros y las adiciones de iOS 27. 

  2. Documentación para desarrolladores de Apple: LongRunningIntent (iOS 27.0 beta). “Una interfaz que usas para extender el tiempo de ejecución en segundo plano de un app intent que realiza una tarea de larga duración.” Declarado como protocol LongRunningIntent : ProgressReportingIntent; el sistema tradicionalmente da a las tareas en segundo plano hasta 30 segundos. 

  3. Documentación para desarrolladores de Apple: performBackgroundTask(options:operation:) (iOS 27.0 beta). Ejecuta una operación en segundo plano con tiempo extendido más allá del límite estándar de 30 segundos; requiere actualizaciones regulares del avance o el sistema puede cancelar la extensión; las Live Activities renderizan el avance automáticamente. 

  4. Documentación para desarrolladores de Apple: LongRunningTaskOptions (iOS 27.0 beta). Opciones para configurar tareas de larga duración; declara requisitos de recursos adicionales, pasados a performBackgroundTask(options:operation:)

  5. Documentación para desarrolladores de Apple: SyncableEntity (iOS 27.0 beta). “Una interfaz que indica que tu entidad tiene un identificador consistente entre dispositivos.” Declarado como protocol SyncableEntity : AppEntity; Siri lo usa para transferir una conversación entre dispositivos. 

  6. Documentación para desarrolladores de Apple: IndexedEntityQuery (iOS 27.0 beta). “Una interfaz que añade soporte de reindexación en Spotlight a tu consulta de entidad.” Declarado como protocol IndexedEntityQuery : EntityQuery where Self.Entity : IndexedEntity

  7. Documentación para desarrolladores de Apple: AppUnionValue (iOS 27.0 beta). “Un protocolo que proporciona identidad de tipo nominal y metadatos para valores de unión.” Declarado como protocol AppUnionValue : TypeDisplayRepresentable; la conformidad la genera la macro @UnionValue

  8. Documentación para desarrolladores de Apple: AppUnionValueCasesProviding (iOS 27.0 beta). Declarado como protocol AppUnionValueCasesProviding : AppEnum; lo conforma automáticamente el enum Cases generado por la macro @UnionValue

  9. Documentación para desarrolladores de Apple: OwnershipProvidingEntity (iOS 27.0 beta). “Un tipo que proporciona al sistema contexto de propiedad y de compartición para un app entity.” Declarado como protocol OwnershipProvidingEntity : AppEntity; pide confirmación en entidades compartidas o de acceso público. 

  10. Documentación para desarrolladores de Apple: EntityOwnership (iOS 27.0 beta). “Un tipo que representa las características de propiedad y de compartición de un app entity.” Declarado como struct EntityOwnership; basado en flags, combinable con un OptionSet

  11. Documentación para desarrolladores de Apple: EntityCollection (iOS 27.0 beta). “Un arreglo de identificadores de entidad que usas para mejorar la eficiencia de operaciones que involucran grandes cantidades de entidades.” Declarado como struct EntityCollection<Entity> where Entity : AppEntity; almacena los identificadores inicialmente y resuelve las instancias completas de forma diferida. 

  12. Documentación para desarrolladores de Apple: RunSystemShortcutIntent (iOS 27.0 beta). “Un app intent que usas en widgets para abrir otra app o realizar un App Shortcut, un atajo personalizado o una acción del sistema.” Declarado como struct RunSystemShortcutIntent; usable solo para inicializar un Button de widget. 

  13. Documentación para desarrolladores de Apple: IntentExecutionTargets (iOS 27.0 beta). “Un conjunto de opciones que describe qué proceso ejecuta un intent o una consulta de entidad.” Declarado como struct IntentExecutionTargets; restringe la ejecución a la app, la extensión de App Intents o cualquier destino disponible. 

  14. Apple, sesión 345 de la WWDC26, “Discover new capabilities in the App Intents framework.” developer.apple.com/videos/play/wwdc2026/345. Apple demuestra LongRunningIntent resolviendo un intent de carga de fotos que seguía fallando dentro del límite de 30 segundos, con el framework gestionando el ciclo de vida de la tarea en segundo plano y exponiendo el avance más un control de detención como Live Activity. 

Artículos relacionados

Foundation Models en iOS 27: control de las llamadas a herramientas

iOS 27 añade GenerationOptions.ToolCallingMode para dirigir cómo usa las herramientas el modelo en el dispositivo, ademá…

14 min de lectura

App Intents 2.0 en iOS 26: Visual Intelligence, snippets interactivos y propiedades diferidas

iOS 26 amplió App Intents con IntentValueQuery para Visual Intelligence, @DeferredProperty para valores asíncronos, snip…

10 min de lectura

The Robots Are Taking Exams in My Search Console

First-party GSC data: 91% of 3.8M impressions fail a human-query filter. Exam questions, pasted errors, and agent sweeps…

10 min de lectura