
-
Conoce App Intents
Obtén información sobre la estructura App Intents y su papel cada vez más crucial dentro de las plataformas para desarrolladores de Apple. Te guiaremos a través de una introducción básica de los conceptos centrales: Intents, entidades, consultas y mucho más. Aprenderás cómo estas piezas encajan entre sí y te permitirán integrar tu app a través de los dispositivos de Apple, desde funcionalidades de software como Spotlight y Atajos hasta funcionalidades de hardware como el botón de Acción. También analizaremos cómo App Intents es la puerta de entrada de tu app para integrarse en Apple Intelligence más adelante.
Capítulos
- 0:00 - Introducción
- 0:45 - Ecosistema de App Intents
- 2:47 - Navegación por la estructura
- 21:15 - Cómo funciona
Recursos
- Accelerating app interactions with App Intents
- Adopting App Intents to support system experiences
- App intent domains
- App Intents
- App Shortcuts
- Building a workout app for iPhone and iPad
- Creating your first app intent
- Integrating actions with Siri and Apple Intelligence
- Making actions and content discoverable and widely available
Videos relacionados
WWDC25
WWDC24
-
Buscar este video…
Hola, soy James, gerente de ingeniería en el equipo Swift Intelligence Frameworks. Me encantaría hablarte sobre App Intents, una estructura para ampliar la detección, visibilidad y capacidades de tu app en todo el sistema y las plataformas de Apple. Primero, platicaremos del papel cada vez más valioso de App Intents dentro de ecosistema de Apple Developer.
Luego, veremos cómo usar la estructura para que las personas en todo el sistema accedan a las acciones y entidades de tu app. Al final, compartiré detalles importantes que debes considerar al escribir tus App Intents.
Antes de analizar cómo usar App Intents, deberíamos hablar del porqué. App Intents es más que la estructura que incorporas a tu app para crear funcionalidades. Es un ecosistema que permite que la funcionalidad de tu app se expanda a todo el sistema.
Tus usuarios obtendrán resultados personalizados en Spotlight, experiencias adaptables para el botón de acción, configurabilidad e interactividad en Widgets, controles sencillos en el Centro de control y acciones personalizadas para el Apple Pencil Pro.
Este año, Spotlight puede invocar las acciones de tu app desde cualquier lugar en la Mac.
La estructura App Intents permite ofrecer vastas experiencias a tus clientes, incluso cuando no estén en tu app. Todo inicia con lo que tu app puede hacer: abrir una nota, iniciar un entrenamiento o agregar un artículo a una lista de compras. Estos son los verbos de tu app y, como ya te imaginarás, los describes cuando creas App Intents o intents. Cuando creas una intent, le das al sistema información adicional para realizar la acción correctamente. Estas toman parámetros y arrojan valores. Y estas entradas y salidas pueden ser tipos nativos de Swift o definidos en tu app. Puedes crear dos valores distintos con App Intents. Para tipos con un conjunto de valores constante usa una App Enum, y para los dinámicos, una App Entity. Las App Enums y App Entities son los sustantivos de tu app. Los atajos de apps permiten mejorar las intenciones clave, las hacen más accesibles y reconocibles. Los atajos de apps aparecen al buscar en Spotlight, usar Siri, configurar el botón de acción y más. Son como las oraciones de tu app, creadas a partir de una intención y los parámetros que esta necesita para ejecutarse. Creo que la mejor forma de aprender es con la práctica. Veamos qué necesito para crear mi primera intent. Amo viajar en familia y estuve trabajando en una app para visitar puntos de referencia en todo el mundo. Esta tiene algunas secciones. Puedo desplazarme por una lista de puntos de referencia, ubicarlos en un mapa o ver mis colecciones. Muchos prefieren la tabla de puntos de referencia. Crearé una App Intent que permita navegar directa y fácilmente a esta sección. ¿Cómo hago eso? Primero, definiré una estructura que adopte el protocolo AppIntent. Los requisitos mínimos para una App Intent son un título y método de ejecución.
El título es una cadena única y localizada que aparecerá como el nombre de la intent. El método de ejecución contiene la lógica. Abriré la vista de puntos de referencia con un navegador compartido. La navegación debe hacerse en el hilo principal, por lo que marcaré @MainActor.
El método de ejecución arroja un IntentResult. Los IntentResults pueden contener desde un diálogo que Siri puede decir hasta un fragmento de vista. Por defecto, ejecutar una intención no pondrá a tu app en primer plano, pero con un diálogo y un fragmento podrás mostrar el resultado de tu acción.
Dado que esta intent pretende navegar por las pantallas, la configuraré para que abra cuando se ejecute. Estableceré la nueva propiedad supportedModes en primer plano para abrir mi app antes de que se ejecute la intención y ya creé mi primera intent. Las intenciones de apps instaladas están en Atajos. Puedo crear un nuevo atajo y agregar mi intención de navegación. Al ejecutarla, mi app se pone en primer plano y abre la vista Puntos de referencia. En mi app también se pueden ver colecciones y ubicar puntos de referencia en un mapa. Sería genial si la intención también pudiera navegar a esas partes de la app. Mi app usa una enum Swift simple para modelar secciones. Para que el tipo sea compatible con la estructura, adoptaré el protocolo AppEnum. AppEnum tiene pocos requisitos. Debe ser instanciable desde una cadena, así que agregaré un valor crudo. Un TypeDisplayRepresentation describe el tipo como un todo y una caseDisplayRepresentation describe cada caso de la enum.
Estas representaciones deben ser constantes, ya que estos datos se usan en tiempo de compilación.
En mi intent, agregaré una variable para contener la navegación. Agregaré @Parameter para convertirlo en un parámetro de intent. Estos actúan como entradas para las intents. Pueden ser obligatorios u opcionales. Lo hice obligatorio para que se garantice la existencia de un valor antes de la ejecución.
Actualizaré el método de ejecución para usar la opción de Navegación y cambiaré el título para reflejar la nueva acción.
Al regresar a mi atajo, ahora la opción de navegación es un parámetro editable. Al ejecutar la intent, Atajos solicitará la sección. Elegiré Mapa y se abrirá directamente esa vista. Los tipos de App Intents están diseñados para ser personalizables. Esto permite colocar los componentes básicos en su lugar y mejorar la experiencia. Agregaré información adicional a la intención para mejorar su uso.
Los atajos mostrarán cada parámetro como una fila. Al tocar la fila aparecerá una lista de valores para ese tipo. Pero hay algunas cosas que puedo hacer para mejorar la experiencia.
Una App Enum requiere un título por cada caso de enum, pero se puede configurar con más información, como un ícono.
Para agregar uno, usaré el inicializador DisplayRepresentation. Luego, agregaré un símbolo a cada caso. Cuando lo haga, Atajos mostrará la imagen en el selector. Puedes configurar las intenciones con una representación fluida llamada Resumen de parámetros. Esta describe la acción y sus parámetros de una manera legible para las personas.
Proporcionaré el resumen con mi parámetro interpolado en la cadena. Los atajos mostrarán el resumen con el parámetro seleccionable en línea para una descripción más útil de la acción.
En realidad, esto aún no parece una oración. Agregaré un título personalizado a mi parámetro.
También agregaré un cuadro de diálogo personalizado cuando se solicite un valor. Como novedad este año, cuando implementes un Resumen de parámetros, con todos los parámetros requeridos, las personas podrán ejecutar tu acción desde Spotlight en la Mac. Para conocer más sobre las nuevas incorporaciones a Spotlight, ve esta sesión.
Al modelar las acciones de tu app como intents, tus clientes crearán atajos y automatizaciones avanzadas. Sin embargo, algunas intenciones son tan centrales para tu app que deben estar disponibles desde la instalación. Puedes proporcionarlas al adoptar Atajos de apps.
Un atajo de app es un tipo que expone automáticamente una App Intent en el sistema. Además, ocupan un lugar destacado al buscar en Spotlight. Con Siri, una frase desencadenante puede activar un atajo de app. Pueden configurarse para activarse con el botón de acción o con el Apple Pencil. Los atajos de app se muestran en la app Atajos sin configuraciones y lo mejor es que se desarrollan con un par de líneas de código. Veamos cómo.
Las apps ofrecen atajos de apps a través de un proveedor. Se debe definir un proveedor único para tu app con todos los atajos. Un atajo de app toma una instancia de una intent, así como frases, un título y una imagen. Las frases de un atajo se pueden decir o escribir a Siri para activarlo. Cada frase debe incluir el marcador applicationName. Pueden incluir hasta un parámetro de intent. Si se proporciona, se creará un atajo para cada valor de ese tipo.
Solo se necesita esta estructura simple para crear un atajo de app. Se mostrarán los atajos de tu app en una nueva sección. Las frases influyen en los atajos de apps que se crean. Al proporcionar una frase sin un parámetro, se creará un atajo con el título y el nombre de la imagen. Como proporcioné una frase con una App Enum, se creará un atajo para cada caso.
Ya puedo ejecutar mi intent con Siri o Spotlight. Los atajos son excelentes para que tus intents sean reconocibles. Para saber más sobre cómo crear atajos de apps, ve esta sesión de la WWDC23.
Los puntos de referencia son centrales en mi app. Sería genial que mis intents permitieran actuar sobre ellos. En Landmarks no puedo usar una App Enum, pues son dinámicos, no constantes. Crearé una App Entity para modelar Landmarks.
Mi app ya tiene un tipo de punto de referencia. Si bien podría adaptar ese tipo a una App Entity, voy a crear una nueva estructura LandmarkEntity. Este tipo será como un puente entre las App Intents y mi modelo de datos subyacente.
Agregaré una ID para que la entidad sea identificable. Es importante que esta ID sea persistente y que puedas buscar instancias de tu entidad con esta ID. Lo explicaremos más tarde. Al igual que los parámetros de una intent, el atributo @Property indica las propiedades de la entidad. Estos se expondrán a tus clientes en Atajos y se podrán usar en acciones de Buscar y filtrar. Este año, puedo agregar Getters a las propiedades de mi entidad, usando el nuevo atributo @ComputedProperty para establecer estos valores. En lugar de copiar valores entre estos tipos, puedo recurrir a mi modelo de datos. Al igual que las App Enums, las entidades requieren una representación del tipo y las instancias.
Las entidades necesitan una pieza de información adicional, una consulta.
A diferencia de una App Enum que tiene un conjunto conocido de valores, las entidades son dinámicas. Mi app puede tener varios puntos de referencia. Las consultas permiten a mi sistema razonar mis entidades. Lo hace respondiendo una serie de preguntas diferentes. La primera pregunta es: “¿Qué entidades existen?”. La consulta permite responder esa pregunta y devolver una colección de entidades coincidentes.
Las consultas admiten variaciones de la pregunta. Por ejemplo, una consulta de cadena pregunta: “¿Existen entidades que coincidan con esta cadena?”. Una de propiedad podría preguntar: “¿Cuáles son los puntos de referencia del estado?”. Las consultas deben responder a una pregunta: “¿Cuál es la entidad para esta ID?”, así el sistema puede referenciar una entidad y resolverla cuando sea necesario. Puedo proporcionar la consulta creando un tipo que siga el protocolo Entity Query. Con el método entities(for:) se puede responder “¿Qué entidad tiene esta ID?”. Toma un conjunto de identificadores y arroja uno de instancias de entidad. Después analizaremos la pregunta “¿Qué entidades existen?”. Las consultas necesitan acceso a una base de datos local u otra dependencia para obtener instancias. Con el atributo @Dependency puedo agregar dependencias a mi consulta. Tengo que registrar mi dependencia con el gestor de dependencias compartido. Debes registrar las dependencias lo antes posible en el ciclo de vida de tu app. Ya con una entidad de lugares famosos, puedo usarla desde mis intenciones. Cuando viajo, me gustaría saber cuál es el punto de referencia más cercano. Crearé una App Intent para verlo. Empezaré con la intent de punto de referencia más cercano. Debo obtener el punto más cercano desde mi modelo de datos. Las dependencias también son compatibles con las intents. Agregaré una. Para mi método de ejecución, agregaré ReturnsValue de LandmarkEntity. Los parámetros de intent también pueden devolverse desde una intent. El valor que se devuelve puede ser una entrada a otra intent, como en un atajo de varios pasos. También devolveré un cuadro y un fragmento. Esto permite que mi intent muestre o hable el resultado. Y puedo implementar mi método de ejecución. Al encontrar el punto más cercano, arrojaré un resultado con la entidad, el cuadro y la vista. Con el cuadro de diálogo y la vista, mis clientes siempre podrán encontrar el punto más cercano sin importar cómo se invocó la intent. Hablando de eso, crear un atajo de app para esta intent facilitará su ejecución aún más. Mis clientes ahora pueden usar Siri o Spotlight para acceder a esta intent incluso si su teléfono está en el bolsillo. Las intents, entidades y consultas son fundamentales para App Intents. Cada protocolo tiene subprotocolos y configuraciones que proporcionan mayor funcionalidad. Veamos cómo puedo mejorar mi App Entity para brindar más experiencias. Me gustaría poder ver fácilmente una foto del punto más cercano. Puedo usar la app Atajos para ayudarme. Crearé un atajo y agregaré la intent Buscar punto de referencia más cercano. Agregaré la acción Mostrar contenido para ver los resultados. Esto representará el resultado de mi intent. Por defecto, esta acción muestra la representación de la entidad, pero puedo elegir otra propiedad de entidad para renderizar.
LandmarkEntity no tiene una imagen, pero tiene una ruta hacia la imagen. Puedo usar el protocolo Transferible para declarar una imagen para la entidad. Transferible es una forma de describir diferentes representaciones de datos para un tipo. Estas representaciones permiten compartir datos entre apps. Ingresaré los datos de imagen como parte de TransferRepresentation. En Atajos, ahora puedo mostrar la representación de imagen de la entidad. Al ejecutar mi atajo, se mostrará la imagen del punto. Declarar una representación de imagen tiene beneficios extra. Puedo usar este valor de imagen como entrada para tomar fotografías, incluso desde otras apps. Para conocer más sobre Transferible, ve estas sesiones.
Quiero aplicar otro cambio a mi entidad para que sea más fácil de encontrar en el sistema. Spotlight proporciona una potente búsqueda semántica entre apps. Las entidades donantes amplían la comprensión del sistema sobre tu contenido. Para que Spotlight indexe mi entidad, puedo adoptar el protocolo IndexedEntity. Es una App Entity que incluye un conjunto de atributos de Core Spotlight.
Ahora puedes agregar claves de indexación de Spotlight en las propiedades. Anotar propiedades permite que Spotlight muestre información más relevante a tus clientes. Al donar entidades indexadas, la estructura crea el elemento de búsqueda y el conjunto de atributos por ti. Luego de donar entidades, las encontrarás en Spotlight. La app se pondrá en primer plano al tocar una entidad. Puedo mejorar esta experiencia y abrir directamente la vista de detalles del punto de referencia. Empezaré creando una intent que se ajuste al protocolo OpenIntent. Las intents que adoptan este protocolo abren la app antes de ejecutarse, por lo que no necesitas agregar un modo compatible. Las intents abiertas deben tener un parámetro target. Al tocar una entidad en Spotlight, se ejecuta una intent abierta coincidente.
En lugar de invocar mi navegador, ahora puedo adoptar el nuevo protocolo TargetContentProviderIntent, diseñado para la navegación. Estas intents no requieren un método de ejecución. En su lugar, puedo adjuntar un modificador onAppIntentExecution. En el cierre, puedo usar el parámetro para realizar una navegación SwiftUI.
Ahora, tocar un lugar desde Spotlight, me llevará directamente a la vista de detalles de este. Me gustaría finalizar esta sección explicando las consultas y cómo proporcionan entidades. Para ver esto en la práctica, crearé un nuevo atajo de app que abra un punto. Agregué un nuevo atajo a mi proveedor junto con dos frases. Una con un parámetro de punto de referencia y otra sin él. Sin embargo, al ejecutar mi atajo no veo ningún punto para elegir. Como habrás adivinado, puedo usar la consulta para ofrecer algunos puntos. Implementaré el método suggestedEntities en Entity Query, para que mis clientes puedan ver sus puntos favoritos. Ahora, al volver a ejecutar la intent, puedo ver la lista de entidades sugeridas. Las entidades sugeridas tienen otro uso. ¿Recuerdas cuando agregué una frase parametrizada? Puedo generar un atajo para cada entidad sugerida invocando el método updateAppShortcutParameters en mi proveedor. Ahora puedo usar Siri y Atajos para navegar fácil y directamente a mis puntos favoritos. Las consultas pueden responder a otras preguntas sobre tus entidades. Si todas tus entidades caben en la memoria, una EnumerableEntityQuery puede devolverlas todas. App Intents pueden obtener consultas más complicadas a partir de esta. EntityPropertyQuery permite devolver una lista ordenada de entidades, dado un conjunto de predicados. Yo aplicaré EntityStringQuery para admitir la búsqueda a partir de una cadena. Arrojaré una lista de puntos donde la cadena coincida con su nombre o descripción. Mis clientes ahora podrán buscar los resultados al configurar una intent que necesita un punto de referencia. Apenas vimos la superficie de App Intents y sus numerosas capacidades. Consulta la documentación de App Intents para ver las formas en que la estructura deleitará a tus usuarios. Me gustaría finalizar explicando la arquitectura que impulsa App Intents. Cuando creas una app con App Intents, tu código es la fuente de la verdad. App Intents no requiere archivos de configuración o instalación. El código fuente Swift se leerá durante la creación para generar su representación de App Intents. Esta representación se almacena dentro de tu app o estructura. Una vez instalada tu app, el sistema usará estos datos para comprender sus capacidades sin necesidad de ejecutarla. Veamos cómo funciona esto. El nombre de la intent se convierte en el identificador único de la acción. El título permite diferenciarla entre otras intents, y la firma de devolución del método de ejecución describe cómo representar el resultado. Dado que este proceso ocurre durante el desarrollo, y no en la ejecución, ciertos valores deben ser constantes. Por ejemplo, el título debe ser constante. Invocar una función o propiedad computarizada genera un error. Este procesamiento ocurre por cada objetivo en tu app. Para compartir correctamente los tipos de App Intent entre los objetivos, debes tener en cuenta algunas cosas. El año pasado, lanzamos la capacidad para que tu app y las extensiones de App Intents consulten los tipos de App Intent definidos en una estructura. Este año, nos complace anunciar que ahora puedes agregar App Intents a tus paquetes Swift y bibliotecas estáticas. Al usar tipos de App Intent en distintos objetivos, debes proporcionar información adicional sobre cada objetivo. Esto garantiza que tus tipos estén bien indexados y validados. Analicemos el tema para ver cómo se hace. Mi app solo tiene un objetivo con todo el código de mis App Intents. Quiero presentar una nueva extensión para alojar algunas intents. Estos objetivos necesitan acceso a Landmarks. Crearé un paquete Swift y moveré mi LandmarkEntity allí. Para compartir tipos entre objetivos, debo registrarlos como un paquete de App Intents. Primero, crearé un paquete de App Intents en el destino de la entidad. Agregaré otro paquete al objetivo de mi app. Puedo agregar una lista de paquetes, así que incluiré el que acabo de crear. Al final, haré lo mismo desde mi extensión. Esto garantiza que el entorno de ejecución de App Intents pueda acceder a los tipos definidos. Usa el paquete de App Intents cuando consultes un código no compilado en una biblioteca estática.
Es hora de concluir. Si este fue tu primer acercamiento a App Intents, comienza agregando el primer atajo a tu app. A partir de ahí, explora la estructura para ver qué puede aportar el mayor valor a tus clientes. Si quieres saber más sobre App Intents, habrá otras sesiones este año. ¡Gracias por acompañarnos!
-
-
3:23 - Navigate Intent
struct NavigateIntent: AppIntent { static let title: LocalizedStringResource = "Navigate to Landmarks" static let supportedModes: IntentModes = .foreground @MainActor func perform() async throws -> some IntentResult { Navigator.shared.navigate(to: .landmarks) return .result() } }
-
5:02 - Navigation Option App Enum
enum NavigationOption: String, AppEnum { case landmarks case map case collections static let typeDisplayRepresentation: TypeDisplayRepresentation = "Navigation Option" static let caseDisplayRepresentations: [NavigationOption: DisplayRepresentation] = [ .landmarks: "Landmarks", .map: "Map", .collections: "Collections" ] }
-
5:38 - Navigate Intent with Parameter
struct NavigateIntent: AppIntent { static let title: LocalizedStringResource = "Navigate to Section" static let supportedModes: IntentModes = .foreground @Parameter var navigationOption: NavigationOption @MainActor func perform() async throws -> some IntentResult { Navigator.shared.navigate(to: navigationOption) return .result() } }
-
6:57 - Case Display Representations with Images
static let caseDisplayRepresentations = [ NavigationOption.landmarks: DisplayRepresentation( title: "Landmarks", image: .init(systemName: "building.columns") ), NavigationOption.map: DisplayRepresentation( title: "Map", image: .init(systemName: "map") ), NavigationOption.collections: DisplayRepresentation( title: "Collections", image: .init(systemName: "book.closed") ) ]
-
7:28 - Navigation Option With Parameter Summary
struct NavigateIntent: AppIntent { static let title: LocalizedStringResource = "Navigate to Section" static let supportedModes: IntentModes = .foreground static var parameterSummary: some ParameterSummary { Summary("Navigate to \(\.$navigationOption)") } @Parameter( title: "Section", requestValueDialog: "Which section?" ) var navigationOption: NavigationOption @MainActor func perform() async throws -> some IntentResult { Navigator.shared.navigate(to: navigationOption) return .result() } }
-
9:22 - App Shortcuts Provider and Navigation Intent App Shortcut
struct TravelTrackingAppShortcuts: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut( intent: NavigateIntent(), phrases: [ "Navigate in \(.applicationName)", "Navigate to \(\.$navigationOption) in \(.applicationName)"a ], shortTitle: "Navigate", systemImageName: "arrowshape.forward" ) } }
-
11:02 - Landmark Entity
struct LandmarkEntity: AppEntity { var id: Int { landmark.id } @ComputedProperty var name: String { landmark.name } @ComputedProperty var description: String { landmark.description } let landmark: Landmark static let typeDisplayRepresentation = TypeDisplayRepresentation(name: "Landmark") var displayRepresentation: DisplayRepresentation { DisplayRepresentation(title: "\(name)") } static let defaultQuery = LandmarkEntityQuery() }
-
13:19 - Landmark Entity Query
struct LandmarkEntityQuery: EntityQuery { @Dependency var modelData: ModelData func entities(for identifiers: [LandmarkEntity.ID]) async throws -> [LandmarkEntity] { modelData .landmarks(for: identifiers) .map(LandmarkEntity.init) } }
-
13:50 - App Dependency Manager
@main struct LandmarksApp: App { init() { AppDependencyManager.shared.add { ModelData() } } }
-
14:18 - Closest Landmark Intent
struct ClosestLandmarkIntent: AppIntent { static let title: LocalizedStringResource = "Find Closest Landmark" @Dependency var modelData: ModelData @MainActor func perform() async throws -> some ReturnsValue<LandmarkEntity> & ProvidesDialog & ShowsSnippetView { let landmark = try await modelData.findClosestLandmark() return .result( value: landmark, dialog: "The closest landmark to you is \(landmark.name)", view: ClosestLandmarkView(landmark: landmark) ) } }
-
15:18 - Closest Landmark App Shortcut
AppShortcut( intent: ClosestLandmarkIntent(), phrases: [ "Find closest landmark in \(.applicationName)" ], shortTitle: "Closest landmark", systemImageName: "location" )
-
16:33 - Transferable
extension LandmarkEntity: Transferable { static var transferRepresentation: some TransferRepresentation { DataRepresentation(exportedContentType: .image) { return try $0.imageRepresentationData } } }
-
17:31 - Indexed Entity
struct LandmarkEntity: IndexedEntity { // ... @Property( indexingKey: \.displayName ) var name: String @Property( indexingKey: \.contentDescription ) var description: String }
-
18:17 - Open Landmark Intent
struct OpenLandmarkIntent: OpenIntent, TargetContentProvidingIntent { static let title: LocalizedStringResource = "Open Landmark" @Parameter(title: "Landmark", requestValueDialog: "Which landmark?") var target: LandmarkEntity } struct LandmarksNavigationStack: View { @State var path: [Landmark] = [] var body: some View { NavigationStack(path: $path) {} .onAppIntentExecution(OpenLandmarkIntent.self) { intent in path.append(intent.target.landmark) } } }
-
19:24 - Open Landmark App Shortcut
AppShortcut( intent: OpenLandmarkIntent(), phrases: [ "Open \(\.$target) in \(.applicationName)", "Open landmark in \(.applicationName)" ], shortTitle: "Open", systemImageName: "building.columns" )
-
19:39 - Suggested Entities
struct LandmarkEntityQuery: EntityQuery { // ... func suggestedEntities() async throws -> [LandmarkEntity] { modelData .favoriteLandmarks() .map(LandmarkEntity.init) } }
-
20:06 - Update App Shortcut Parameters
TravelTrackingAppShortcuts.updateAppShortcutParameters()
-
20:25 - EnumerableEntityQuery
extension LandmarkEntityQuery: EnumerableEntityQuery { func allEntities() async throws -> [LandmarkEntity] { // ... } }
-
20:36 - EntityPropertyQuery
extension LandmarkEntityQuery: EntityPropertyQuery { static var properties = QueryProperties { // ... } static var sortingOptions = SortingOptions { // ... } func entities( matching comparators: [Predicate<LandmarkEntity>], mode: ComparatorMode, sortedBy: [Sort<LandmarkEntity>], limit: Int? ) async throws -> [LandmarkEntity] { // ... } }
-
20:44 - EntityStringQuery
extension LandmarkEntityQuery: EntityStringQuery { func entities(matching: String) async throws -> [LandmarkEntity] { modelData .landmarks .filter { $0.name.contains(matching) || $0.description.contains(matching) } .map(LandmarkEntity.init) } }
-
23:10 - App Intents Package
// TravelTrackingKit public struct TravelTrackingKitPackage: AppIntentsPackage {} public structaLandmarkEntity: AppEntity {} // TravelTracking struct TravelTrackingPackage: AppIntentsPackage { static var includedPackages: [any AppIntentsPackage.Type] { [TravelTrackingKitPackage.self] } } struct OpenLandmarkIntent: OpenIntent {} // TravelTrackingAppIntentsExtension struct TravelTrackingExtensionPackage: AppIntentsPackage { static var includedPackages: [any AppIntentsPackage.Type] { [TravelTrackingKitPackage.self] } } struct FavoriteLandmarkIntent: AppIntent {}
-
-
- 0:00 - Introducción
Obtén información sobre App Intents una estructura que puedes utilizar para mejorar la capacidad de descubrimiento y la funcionalidad de las apps en todas las plataformas de Apple. Los temas incluyen la importancia de la estructura, la implementación y las mejores prácticas para escribir en Apps Intents.
- 0:45 - Ecosistema de App Intents
App Intents es un ecosistema que permite que las apps extiendan su funcionalidad a todo el sistema Spotlight, Botón de acción, Widgets, Centro de control y Apple Pencil Pro. Las personas pueden realizar acciones en la app desde cualquier lugar, incluso cuando no están en la app. Defines las acciones de la app como intenciones, que pueden tomar parámetros y devolver valores utilizando enumeraciones de app para constantes o entidades de app para tamaños de letra dinámicos. Los Atajos a apps, creados a partir de intenciones y parámetros, mejoran la accesibilidad y la capacidad de descubrimiento a través de Spotlight, Siri y el botón de acción.
- 2:47 - Navegación por la estructura
La app de ejemplo explora lugares famosos de todo el mundo. Para mejorar la experiencia del usuario, implementa App Intents, que permiten a las personas realizar acciones directamente desde Siri, Atajos y Spotlight. El proceso implica definir estructuras que adoptan el protocolo App Intents, especificando títulos, métodos de ejecución y resultados de intenciones. Agrega parámetros a las intenciones, lo que permite a las personas elegir secciones específicas de la app, como la cuadrícula de puntos de referencia o la vista del mapa. Para que la app sea más fácil de descubrir y usar, se crean Atajos a apps, que exponen automáticamente las intenciones en todo el sistema. También modelan datos dinámicos como puntos de referencia utilizando entidades de app, lo que permite a las personas realizar acciones en puntos de referencia específicos a través de intenciones. En la estructura de App Intents, las entidades de la app representan datos dinámicos, como puntos de referencia. Las consultas son componentes esenciales que permiten al sistema razonar sobre estas entidades. Responden varias preguntas, incluida la recuperación de todas las entidades, la coincidencia de cadenas o propiedades específicas y la referencia única a las entidades por ID. Puede personalizar consultas utilizando diferentes tipos, como EntityStringQuery y EntityPropertyQuery y estas consultas pueden depender de bases de datos locales u otros recursos. Las dependencias se pueden agregar a las consultas mediante el atributo @Dependency. Registra las dependencias lo antes posible en el ciclo de vida de tu app. Al usar App Intents, puedes crear acciones personalizadas que se pueden realizar usando Siri, Spotlight o Atajos. Al devolver tipos de entidades desde las intenciones, estas acciones se pueden encadenar entre sí en atajos de varios pasos. Para mejorar la experiencia del usuario, puedes hacer que las entidades sean transferibles, lo que permitirá compartirlas entre apps. La adopción del protocolo de entidad indexada permite a Spotlight realizar búsquedas semánticas. También puedes crear intenciones abiertas para navegar directamente a vistas específicas dentro de la app cuando se tocan entidades en Spotlight.
- 21:15 - Cómo funciona
App Intents utiliza el código fuente Swift en el momento de la compilación para generar una representación de App Intents, que luego se almacena dentro de la app o la estructura. Esto permite que el sistema comprenda las capacidades de la app sin ejecutarla. El nombre de la intención sirve como su identificador único; el título ayuda a las personas a diferenciar entre intenciones y la firma de retorno del método 'perform' define cómo representar el resultado. Es necesario proporcionar valores constantes para ciertas propiedades de intención porque el procesamiento se produce en el momento de la compilación. Para compartir tipos de App Intent entre objetivos, como una app y su extensión, puede utilizar paquetes Swift o bibliotecas estáticas. Debe registrar cada objetivo como un paquete de App Intents para garantizar la indexación y validación adecuadas de los tipos compartidos por parte del tiempo de ejecución de App Intents.