App Intents 2.0 en iOS 26: Visual Intelligence, snippets interactivos y propiedades diferidas
App Intents llegó en iOS 16 como la API de acciones estructuradas de Apple para Shortcuts, Siri y Spotlight; iOS 17 lo amplió para los widgets impulsados por App Intents; iOS 18 lo convirtió en el contrato para la superficie de acciones de Apple Intelligence. iOS 26 extiende App Intents a Visual Intelligence (resultados de búsqueda de imágenes desde apps de terceros), snippets interactivos (pequeñas ventanas emergentes de UI que se integran en contextos del sistema), anotaciones de vista de entidades (cómo se muestra una entidad en línea) y @DeferredProperty (propiedades de entidad calculadas de forma asíncrona)1. Las extensiones no cambian el modelo central de App Intents; añaden nuevas superficies de participación que una app puede adoptar.
Este post recorre las novedades de iOS 26 frente a la documentación de Apple. El enfoque es “qué nuevas superficies gana una adopción existente de App Intents al añadir las conformidades de iOS 26”, porque la mayoría de las apps con App Intents ya tienen los tipos fundamentales en su lugar, y el trabajo de iOS 26 consiste en extender esos tipos a nuevos contextos.
TL;DR
IntentValueQueryes el nuevo protocolo para la integración con Visual Intelligence. La consulta acepta unSemanticContentDescriptor(el contexto visual del usuario) y devuelve un arreglo de instancias deAppEntityque la app considera relevantes2.@DeferredPropertydeclara una propiedad de entidad cuyo valor se calcula de forma asíncrona. La propiedad se carga cuando el sistema realmente la necesita, evitando el costo inicial para entidades con muchos campos baratos de mostrar y unos pocos costosos de calcular.- Los App Intents Snippets interactivos permiten a una app presentar una pequeña ventana emergente (con botones, texto, controles) dentro de contextos del sistema como Spotlight, Visual Intelligence o la superficie de respuesta de Siri. El snippet es una vista SwiftUI vinculada al resultado del App Intent.
- Las anotaciones de vista de entidades permiten a una app declarar cómo debe renderizarse un
AppEntityen distintos contextos del sistema (una fila compacta en Spotlight, una tarjeta destacada en Visual Intelligence, un widget al estilo Live Activity). - El post de App Intents del clúster cubrió el modelo fundamental; este post lo extiende a las nuevas superficies de participación de iOS 26. El post App Intents vs herramientas MCP del clúster cubre la cuestión de enrutamiento entre la superficie de intents de Apple Intelligence y las herramientas MCP de agente general.
Visual Intelligence: IntentValueQuery y SemanticContentDescriptor
La adición destacada de App Intents en iOS 26 es la integración con Visual Intelligence2. El flujo:
- El usuario toma una foto, captura una pantalla o apunta la cámara a un objeto.
- La capa de Visual Intelligence del sistema extrae el contexto visual y semántico (qué hay en la imagen, qué podría querer saber el usuario al respecto).
- El sistema consulta a cada app que registró un
IntentValueQuerycon ese contexto semántico. - Cada app devuelve instancias relevantes de
AppEntity; el sistema las agrega y las presenta en la UI de Visual Intelligence. - El usuario toca una entidad para entrar en la app de origen en el contexto adecuado.
La superficie del desarrollador es una struct que se conforma a IntentValueQuery con un método values(for:) que recibe un SemanticContentDescriptor:
import AppIntents
struct ProductLookupQuery: IntentValueQuery {
func values(for descriptor: SemanticContentDescriptor) async throws -> [Product] {
// descriptor.labels: detected category and content labels
// descriptor.pixelBuffer: the visual content as a CVReadOnlyPixelBuffer
// (use VideoToolbox/CoreImage to convert if needed)
let candidates = try await catalog.search(labels: descriptor.labels)
return candidates.map(Product.init)
}
}
El SemanticContentDescriptor lleva dos campos que el sistema rellena: labels (un arreglo de etiquetas detectadas de categoría y contenido como “wine bottle”, “pinot noir”, “label text”, etc.) y pixelBuffer (los datos de imagen subyacentes como un CVReadOnlyPixelBuffer para apps que quieran ejecutar sus propios modelos de visión sobre el contenido). El trabajo de la app es mapear esas señales a sus propios datos y devolver las entidades coincidentes.
El patrón de adopción correcto: una app de compras implementa la consulta contra su catálogo de productos (contexto visual → productos coincidentes), una app de vinos contra su base de datos de botellas (imagen de etiqueta → entrada de vino), una app de recetas contra su biblioteca de recetas (foto de ingrediente → recetas coincidentes).
@DeferredProperty: valores de entidad asíncronos
Los tipos AppEntity existentes declaran sus propiedades de forma estática. Cada propiedad debe calcularse antes de devolver la entidad. Para entidades con propiedades de costo mixto (título/subtítulo/imagen rápidos, descripción detallada lenta desde el servidor), el cálculo de todo o nada es un desperdicio.
@DeferredProperty (iOS 26+) declara una propiedad como calculada de forma asíncrona3:
import AppIntents
struct Recipe: AppEntity {
static var typeDisplayRepresentation = TypeDisplayRepresentation(...)
static var defaultQuery = RecipeQuery()
@Property(title: "Title")
var title: String
@Property(title: "Cuisine")
var cuisine: String
@DeferredProperty(title: "Detailed Instructions")
var instructions: String {
get async throws {
try await loadInstructionsFromBackend(id: id)
}
}
}
El getter de la propiedad diferida es asíncrono; se ejecuta solo cuando el sistema realmente necesita el valor (por ejemplo, cuando se selecciona la entidad para mostrar el detalle). Para entidades devueltas por una consulta y usadas solo para la UI de selección, la propiedad diferida nunca se calcula.
El patrón es adecuado para cualquier entidad con campos de construcción rápida (id, título, resumen) más campos de construcción costosa (cuerpo completo, métricas calculadas, datos obtenidos del servidor). Sin @DeferredProperty, el desarrollador o bien calcula todo (desperdicio) o bien calcula solo los campos baratos y añade un intent separado de “cargar detalle” (más complejo).
Snippets interactivos y SnippetIntent
iOS 26 introduce el protocolo dedicado SnippetIntent para interacciones con forma de snippet, junto al patrón existente de AppIntent que se conforma a ShowsSnippetView de versiones anteriores4. SnippetIntent añade un método estático reload() que el sistema puede llamar para refrescar el contenido del snippet sin una reinvocación completa del intent:
struct WeatherSnippet: SnippetIntent {
static var title: LocalizedStringResource = "Weather Snippet"
@Parameter(title: "City")
var city: City
func perform() async throws -> some IntentResult & ShowsSnippetView {
let forecast = try await weatherService.forecast(for: city)
return .result(view: ForecastSnippet(forecast: forecast))
}
static func reload() async throws {
// Triggered by the system when it wants fresh snippet data
// (e.g., after the data source signals an update)
}
}
Para intents no específicos de snippet que quieran adjuntar una vista de snippet a su respuesta, el patrón existente de AppIntent + ShowsSnippetView sigue funcionando:
struct WeatherForecastIntent: AppIntent {
static var title: LocalizedStringResource = "Weather Forecast"
@Parameter(title: "City")
var city: City
func perform() async throws -> some IntentResult & ProvidesDialog & ShowsSnippetView {
let forecast = try await weatherService.forecast(for: city)
return .result(
dialog: "Here's the forecast for \(city.name).",
view: ForecastSnippet(forecast: forecast)
)
}
}
struct ForecastSnippet: View {
let forecast: Forecast
var body: some View {
VStack(alignment: .leading) {
Text(forecast.headline).font(.headline)
HStack {
ForEach(forecast.days) { day in
DayCell(day: day)
}
}
Button("Open in App") {
// App-launching action wired via App Intents
}
}
.padding()
}
}
La conformidad ShowsSnippetView del tipo de resultado le indica al sistema que renderice la vista SwiftUI junto al diálogo. El snippet es interactivo: los botones dentro de él pueden disparar otros App Intents, el usuario puede hacer scroll, la vista participa en la capa de interacción del sistema.
Los casos que merecen un snippet interactivo: pronósticos del clima, eventos de calendario, tiempos de tránsito, marcadores deportivos, seguimiento de paquetes. En cualquier lugar donde el usuario quiera más que una respuesta de diálogo de una sola línea desde la superficie del sistema.
Anotaciones de vista de entidades
Las anotaciones de vista de entidades permiten a una app declarar cómo debe renderizarse un AppEntity en distintos contextos del sistema5. El mecanismo extiende DisplayRepresentation con múltiples variantes:
struct Recipe: AppEntity {
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(
title: "\(title)",
subtitle: "\(cuisine) - \(time) min",
image: .init(named: imageName)
)
}
}
El modelo clásico devuelve un único DisplayRepresentation. iOS 26 permite que las entidades proporcionen variantes específicas de contexto entre las que el sistema elige según dónde esté renderizando (lista compacta, tarjeta destacada, resultado de Spotlight, panel de Visual Intelligence). El framework elige la variante correcta por contexto; la app declara cada una.
El patrón da soporte a apps que necesitan que el renderizado de la entidad difiera entre, por ejemplo, una lista densa de Spotlight y una respuesta de tarjeta única en Visual Intelligence. Las variantes se componen sin que la app tenga que detectar el contexto.
Composición con App Intents existentes
Las adiciones de iOS 26 se componen con las primitivas existentes de App Intents:
- El
AppShortcutsProviderde una app (cubierto en Accesibilidad como plataforma) registra atajos para voz, botón de acción y Spotlight. - Cada
AppShortcutreferencia unAppIntent, que tiene propiedades@Parameterresueltas a partir de la solicitud del usuario. - El método
AppIntent.perform()devuelve un tipo de resultado que puede incluir una vista de snippet (ShowsSnippetView) o un diálogo (ProvidesDialog). - Los tipos
AppEntityreferenciados por los parámetros del intent ahora soportan@DeferredPropertyy anotaciones de vista de entidades. - Los nuevos tipos
IntentValueQuerypermiten que las mismas entidades aparezcan en Visual Intelligence.
La forma: el modelo existente se preserva; el trabajo de iOS 26 consiste en añadir nuevos tipos (consultas) y nuevas anotaciones (diferidas, variantes de vista) a la misma superficie de entidades.
Fallas comunes
Tres patrones de fallas en la adopción de App Intents 2.0:
IntentValueQuery que devuelve resultados sin acotar. Una consulta que devuelve todos los productos que coinciden con los términos de búsqueda del descriptor, independientemente de la relevancia, diluye la experiencia de Visual Intelligence. Solución: acotar la consulta (top-N por relevancia, ponderada por recencia, personalizada por usuario) para que cada entidad devuelta se gane su lugar en la UI del sistema.
@DeferredProperty para valores rápidos. El mecanismo diferido es para cómputo genuinamente costoso. Marcar una propiedad rápida en memoria como diferida añade sobrecarga asíncrona sin beneficio. Solución: reservar @DeferredProperty para propiedades que realmente compensan al diferirse (peticiones al servidor, cálculos grandes, invocaciones de modelos de ML).
Snippets interactivos que son apps completas. Un snippet es una superficie de UI compacta; tratarlo como una mini-app produce snippets que se sienten apretados o son lentos al renderizar. Solución: mantén los snippets enfocados en la respuesta inmediata y una o dos acciones relacionadas; usa el botón “Abrir en la app” para entregar los flujos complejos a la app completa.
Qué significa este patrón para apps en iOS 26+
Tres conclusiones.
-
Añade
IntentValueQuerypara cualquier app con contenido visual. Compras, recetas, productos, ubicaciones, objetos identificables. La integración con Visual Intelligence es la nueva superficie de descubrimiento; las apps que no participan son invisibles allí. -
Usa
@DeferredPropertypara campos de entidad costosos. Descripciones detalladas, métricas calculadas, datos obtenidos del servidor. El patrón asíncrono por defecto coincide con el código Swift moderno y mantiene rápidos los retornos de entidades baratas de construir. -
Adopta snippets interactivos para tipos de consulta de alto valor. Clima, calendario, tránsito, deportes, seguimiento de paquetes. La UI de snippet mantiene a los usuarios en la superficie de respuesta del sistema para los casos donde un diálogo de una sola línea no es suficiente pero lanzar la app completa es excesivo.
El clúster completo de Apple Ecosystem: App Intents tipados; servidores MCP; la cuestión del enrutamiento; Foundation Models; la distinción LLM entre runtime y tooling; tres superficies; el patrón de única fuente de verdad; dos servidores MCP; hooks para desarrollo Apple; Live Activities; el contrato de runtime de watchOS; internals de SwiftUI; el modelo mental espacial de RealityKit; disciplina de esquemas en SwiftData; patrones de Liquid Glass; envío multiplataforma; la matriz de plataformas; Vision framework; Symbol Effects; inferencia con Core ML; API de Writing Tools; Swift Testing; Privacy Manifest; accesibilidad como plataforma; tipografía SF Pro; patrones espaciales de visionOS; Speech framework; migraciones de SwiftData; motor de foco de tvOS; internals de @Observable; protocolo Layout de SwiftUI; SF Symbols personalizados; HDR en AVFoundation; ciclo de vida de workout en watchOS; sobre qué me niego a escribir. El hub está en la serie de Apple Ecosystem. Para un contexto más amplio de iOS con agentes de IA, consulta la guía de iOS Agent Development.
FAQ
¿Necesito tener Apple Intelligence habilitado para probar IntentValueQuery?
Para pruebas completas de Visual Intelligence, sí. Visual Intelligence requiere hardware compatible con Apple Intelligence (iPhone 15 Pro o más reciente, Mac M1 o más reciente) con iOS 26+ y Apple Intelligence habilitado. Para desarrollo, puedes probar la consulta en pruebas unitarias construyendo directamente un SemanticContentDescriptor y llamando al método values(for:) de la consulta sin la pila completa del sistema.
¿Puede @DeferredProperty lanzar excepciones?
Sí. La firma del getter asíncrono es get async throws, y las excepciones se propagan al sistema. El sistema maneja la falla mostrando la entidad sin el valor de la propiedad diferida (o mostrando un estado de error en algunos contextos). Las apps deben fallar de forma elegante y devolver estados de error significativos en lugar de fallar abruptamente.
¿El contenido de los snippets interactivos soporta animaciones?
Sí, con las primitivas estándar de animación de SwiftUI. La vista del snippet se ejecuta en la superficie de respuesta del sistema, que soporta la misma infraestructura de animación que SwiftUI dentro de la app. Recurre al post Symbol Effects del clúster para el vocabulario de animación que coincide con las convenciones de la plataforma.
¿Cómo interactúan las anotaciones de vista de entidades con los widgets?
Los widgets son una superficie WidgetKit aparte; las anotaciones de vista de entidades aplican dentro de los contextos de App Intents (Spotlight, Visual Intelligence, respuestas de Siri). Para una app que expone los mismos datos como un AppEntity y como un widget, las dos superficies requieren declaraciones de UI separadas. Las apps suelen compartir el modelo de datos subyacente y escribir vistas de presentación delgadas por superficie.
¿Cuál es la relación entre esto y las herramientas MCP?
App Intents es la superficie de intents de Apple Intelligence; las herramientas MCP son el protocolo agente-servidor para LLMs generales. iOS 26 añade Visual Intelligence a App Intents (la superficie de Apple). Para agentes que no son de Apple (Claude, clase GPT), las herramientas MCP que se ejecutan local o remotamente cubren el mismo territorio conceptual. El post App Intents vs herramientas MCP del clúster cubre la cuestión del enrutamiento.
¿Se puede combinar IntentValueQuery con EntityQuery?
Sí. Sirven a superficies distintas: EntityQuery es para cuando el usuario escribe o pronuncia el nombre de una entidad (Spotlight, Siri); IntentValueQuery es para cuando el usuario está en Visual Intelligence con contexto de imagen. El AppEntity de una app puede tener ambas consultas registradas; el sistema elige la correcta según el contexto.
Referencias
-
Documentación para desarrolladores de Apple: App Intents. La referencia del framework que cubre
AppIntent,AppEntity, consultas, parámetros y las adiciones de iOS 26. ↩ -
Apple Developer: Explore new advances in App Intents (sesión 275 de WWDC 2025). La introducción de
IntentValueQuery,SemanticContentDescriptory la integración con Visual Intelligence. ↩↩ -
Documentación para desarrolladores de Apple:
@DeferredProperty(). La macro de propiedad de entidad calculada de forma asíncrona introducida para App Entities en iOS 26. Cobertura en la sesión 275 de WWDC 2025 (Explore new advances in App Intents). ↩ -
Documentación para desarrolladores de Apple: App Intents Snippets interactivos mediante el tipo de resultado
ShowsSnippetViewcombinado con vistas SwiftUI que se renderizan en contextos del sistema (Spotlight, Visual Intelligence, área de respuesta de Siri). ↩ -
Documentación para desarrolladores de Apple:
DisplayRepresentationy anotaciones de vista de entidades. El mecanismo para declarar cómo se renderiza unAppEntityen distintos contextos del sistema. ↩