App Intents no iOS 27: execução em segundo plano, sincronização e Spotlight
O App Intents chegou no iOS 16 como a API tipada e de ações estruturadas da Apple para Atalhos, Siri e Spotlight; o iOS 17 o estendeu para widgets movidos por App Intents; o iOS 18 o transformou no contrato da superfície de ações do Apple Intelligence; o iOS 26 o levou para a Visual Intelligence e os snippets interativos. O iOS 27 muda novamente o formato da aposta, e a mudança é mecânica, não cosmética: um intent agora pode rodar além do limite de 30 segundos em segundo plano, uma entidade pode carregar uma identidade que sobrevive à viagem entre os dispositivos de um usuário e uma query pode reparar seu próprio índice do Spotlight quando o sistema pede. O iOS 27 acrescenta capacidade, não enfeite.1
Cada release anterior ampliava quem podia chamar seus intents. O iOS 27 amplia o que seus intents podem fazer depois de chamados. Um intent de sincronização que opera sobre alguns milhares de registros costumava competir com um cronômetro de 30 segundos e perder; agora ele pede mais fôlego ao sistema e relata o progresso enquanto trabalha. Uma entidade que significava uma coisa no iPhone e outra no Mac agora resolve para o mesmo objeto nos dois. Este post percorre a superfície do iOS 27 confrontada com a documentação da Apple, com o mesmo enquadramento do resto do cluster: o que um app que já oferece App Intents precisa acrescentar para ganhar cada nova capacidade.
TL;DR
LongRunningIntentestende o tempo de execução de um intent em segundo plano além do limite de 30 segundos do sistema. Você envolve o trabalho emperformBackgroundTask(options:operation:)e passaLongRunningTaskOptions; o protocolo refinaProgressReportingIntent, então relatar o progresso é uma exigência, não uma opção. As Live Activities renderizam esse progresso automaticamente.234SyncableEntitydeclara que umAppEntitycarrega um identificador consistente entre os dispositivos de um usuário, o que permite ao sistema referir-se ao mesmo objeto no iPhone, no Mac e no Watch (a Siri usa isso para passar uma conversa de um dispositivo para outro).5IndexedEntityQueryadiciona suporte à reindexação no Spotlight a umaEntityQuery, então, quando o sistema sinaliza um problema com o índice do seu app, ele pode pedir à sua query que redoe as entidades afetadas.6AppUnionValueeAppUnionValueCasesProviding(gerados pela macro@UnionValue) permitem que um único parâmetro aceite vários tipos de entidade distintos, com interface de seletor e resumos de parâmetros adequados.78OwnershipProvidingEntity,EntityOwnershipeEntityCollectioncobrem a confirmação consciente de posse e a eficiência em lote;RunSystemShortcutIntenteIntentExecutionTargetscobrem ações do sistema iniciadas por widgets e qual processo executa um intent.910111213
A barreira dos 30 segundos: LongRunningIntent
O limite de execução em segundo plano tem sido o teto silencioso do que um App Intent podia fazer. Quando o sistema executa um intent em segundo plano (o usuário pede para a Siri sincronizar, depois bloqueia o telefone e o guarda no bolso), ele tradicionalmente concede cerca de 30 segundos para terminar.2 Para registrar um copo de água isso é generoso. Para sincronizar uma biblioteca, rodar inferência no dispositivo ou processar um arquivo grande, 30 segundos são uma guilhotina: o sistema mata a tarefa no meio de uma escrita e o usuário recebe um resultado pela metade.
O iOS 27 introduz LongRunningIntent, um protocolo que um intent adota para pedir ao sistema uma janela estendida em segundo plano.2 A Apple nomeia os casos de uso diretamente na documentação: operações de arquivo, sincronização de dados, inferência de machine learning e processamento de dados sobre um conjunto grande o suficiente. A declaração já revela a restrição mais importante antes de você escrever uma única linha:
protocol LongRunningIntent : ProgressReportingIntent
LongRunningIntent refina ProgressReportingIntent.2 Você não pode adotar o protocolo de execução prolongada sem também relatar o progresso, por design. O tempo de execução estendido é um privilégio que o sistema concede condicionalmente, e a condição é que você continue dizendo a ele o quanto já avançou. Pare de relatar e o sistema pode revogar a extensão e encerrar a tarefa mais cedo.3
O trabalho vai dentro de performBackgroundTask(options:operation:):
@discardableResult
func performBackgroundTask<T>(
options: LongRunningTaskOptions = [],
operation: @escaping () async throws -> T
) async throws -> T
Você chama o método a partir do corpo perform() do seu intent e coloca o código custoso no closure operation. O método estende automaticamente seu tempo de execução além do limite padrão de 30 segundos nas plataformas que o impõem; você não inicia uma tarefa de segundo plano separada nem gerencia um UIBackgroundTaskIdentifier por conta própria.3 Um intent de sincronização de biblioteca fica assim:
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()
}
}
Duas coisas merecem explicação, porque os tutoriais as pulam.
A propriedade progress é o contrato, não telemetria. A Apple é explícita: enquanto sua operação roda, atualize o Progress da conformidade ProgressReportingIntent regularmente, e, se você não fizer isso, o sistema pode cancelar a extensão do tempo de execução e encerrar sua tarefa prematuramente.3 Relatar progresso em um intent comum é uma gentileza. Em um LongRunningIntent é o batimento cardíaco que mantém a extensão viva.
LongRunningTaskOptions declara requisitos de recursos. O valor das opções (uma struct no estilo OptionSet que tem [] como padrão) informa ao sistema sobre necessidades adicionais de recursos da tarefa, que ele leva em conta no tempo de execução que concede.4 Um conjunto vazio é o caso comum. Você recorre a opções explícitas quando o trabalho precisa de mais do que o perfil padrão.
O ganho, além de sobreviver aos 30 segundos: as Live Activities renderizam o progresso de graça. A documentação afirma que as Live Activities exibem o progresso da tarefa do intent usando informações que recebem automaticamente de performBackgroundTask, desenhando o título, o subtítulo e uma barra de progresso a partir dos valores que seu código relata.3 Uma sincronização longa iniciada por voz aparece na Tela Bloqueada como uma barra de progresso ao vivo sem que você construa uma única view de Live Activity para isso. O intent relata, o sistema renderiza.
LongRunningIntent, com um botão de parar na Live Activity para que a pessoa possa cancelá-lo a qualquer momento.
Na sessão 345, a Apple demonstra LongRunningIntent contra um caso de falha real, um upload de fotos que continuava morrendo dentro da janela de 30 segundos, e mostra o sistema gerenciando o ciclo de vida da tarefa de segundo plano enquanto exibe o progresso e um controle de cancelamento como uma Live Activity.14
Identidade consistente: SyncableEntity
Um AppEntity tem um id. Em um único dispositivo esse identificador só precisa ser único dentro do app. O problema começa no momento em que um usuário tem mais de um dispositivo, o que, no ecossistema da Apple, é o padrão. O “Projeto Atlas” que o usuário discutiu com a Siri no iPhone precisa ser reconhecivelmente o mesmo “Projeto Atlas” quando ele retoma a conversa no Mac. Se o identificador local do iPhone for diferente do identificador do Mac, o sistema tem dois objetos não relacionados e nenhuma forma de conectá-los.
SyncableEntity é a resposta do iOS 27:5
protocol SyncableEntity : AppEntity
Adotá-lo declara que o identificador da sua entidade é o mesmo entre dispositivos. A presença do protocolo diz ao sistema que ele pode se referir à sua entidade de forma consistente de um dispositivo para outro. A Apple dá o ganho concreto: a Siri usa essa capacidade para transferir uma conversa de um dispositivo para outro.5
O custo de adoção depende inteiramente de onde vêm seus identificadores. Se suas entidades já usam um identificador estável entre dispositivos (um UUID emitido pelo servidor, o nome de um registro do iCloud), você adota SyncableEntity sem nenhuma outra mudança, porque o valor que você já armazena é o valor de que o sistema precisa.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
}
A armadilha é o app que cunha um novo identificador local em cada dispositivo (um ID de linha autoincremental, um UUID por instalação). Esses identificadores são únicos localmente e sem sentido entre dispositivos. A orientação da Apple para esse caso: adote o protocolo e ancore sua identidade no valor que de fato é estável, para que o sistema tenha algo durável em que se apoiar.5 A sincronização era o problema difícil que as equipes resolviam à mão com seu próprio encanamento de iCloud. SyncableEntity move a declaração de identidade entre dispositivos para dentro do framework, onde a Siri e o restante do sistema podem agir sobre ela.
Busca que se autorrepara: IndexedEntityQuery
O iOS 16 permitiu doar instâncias de IndexedEntity ao Spotlight para que entidades individuais se tornassem pesquisáveis. O ponto cego era o reparo. Índices ficam desatualizados, corrompem ou ficam para trás após uma migração, e, até o iOS 27, o único recurso do sistema era apoiar-se no delegate CSSearchableIndex do seu app ou na sua CSImportExtension.
IndexedEntityQuery fecha essa lacuna ao permitir que o sistema peça à sua query que reindexe:6
protocol IndexedEntityQuery : EntityQuery where Self.Entity : IndexedEntity
A cláusula where é a pré-condição: a entidade da query precisa estar em conformidade com IndexedEntity, porque reindexar só faz sentido para entidades que você doa ao Spotlight em primeiro lugar.6 Quando o sistema encontra um problema com o índice de um app, ele chama os métodos deste protocolo se o seu tipo de query o adotar; se a sua query não adotar, o Spotlight continua pedindo ao seu objeto CSSearchableIndex (ou à sua CSImportExtension, se você doou associando a entidade a esse tipo) que faça o trabalho.6 Você implementa os métodos para buscar as entidades solicitadas e doá-las novamente por meio do seu índice pesquisável 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)
}
}
O valor é operacional. Um app que acerta IndexedEntityQuery participa do ciclo de recuperação do Spotlight: o sistema percebe que o índice está errado e o app fornece dados novos sob demanda, em vez de o usuário perder silenciosamente resultados de busca até a próxima redoação completa. O post fundamental sobre App Intents do cluster cobriu a exposição básica de IndexedEntity para tornar entradas pesquisáveis; IndexedEntityQuery é a camada de manutenção por cima.
Um parâmetro, vários tipos: AppUnionValue
Muitos intents reais recebem um parâmetro que legitimamente é um de vários tipos. “Compartilhar isto”, em que “isto” é uma foto, um documento ou um link. As soluções alternativas anteriores ao iOS 27 eram feias: intents separados por tipo, ou um discriminador de string mais parâmetros opcionais que a interface de seletor não conseguia renderizar de forma limpa.
O iOS 27 adiciona AppUnionValue para parâmetros de união tipados:7
protocol AppUnionValue : TypeDisplayRepresentable
Um valor de união em conformidade com o protocolo funciona como um parâmetro de Atalhos com metadados ricos, de modo que o sistema pode apresentar um seletor apropriado e um resumo de parâmetro sensato entre os tipos membros.7 Você não escreve a conformidade à mão. A macro @UnionValue a gera, e a mesma macro gera um enum aninhado Cases que está em conformidade com AppUnionValueCasesProviding:78
protocol AppUnionValueCasesProviding : AppEnum
AppUnionValueCasesProviding é conformado automaticamente pelo enum Cases que a macro emite.8 Ele faz a ponte do enum de casos de volta ao tipo de valor de união e herda metadados por meio da sua conformidade com AppEnum, o que é o que dá a cada caso seu nome de exibição no seletor.8 Na prática, você escreve a união e a anota:
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()
}
}
A macro @UnionValue cuida das conformidades AppUnionValue e AppUnionValueCasesProviding; se você quiser metadados personalizados além dos padrões, implementa os requisitos do protocolo em uma extensão.7 Um parâmetro, três tipos válidos, um seletor que sabe como mostrar os três.
Posse e eficiência
Duas preocupações distintas do iOS 27 compartilham esta seção porque ambas protegem o sistema de agir descuidadamente sobre seus dados: confirmação consciente de posse e eficiência em operações em lote.
Confirmando ações destrutivas: OwnershipProvidingEntity
Quando seu app passa entidades para intents e as retorna em resultados, o Apple Intelligence, a Siri e atalhos personalizados podem agir sobre essas entidades entre apps. Para ações destrutivas ou sensíveis (excluir uma entidade, atualizar uma compartilhada), você quer uma confirmação que carregue o contexto certo. OwnershipProvidingEntity fornece isso:9
protocol OwnershipProvidingEntity : AppEntity
Coloque sua entidade em conformidade com ele e o sistema pede confirmação, com o contexto apropriado no diálogo, quando um intent age sobre entidades compartilhadas ou publicamente acessíveis.9 O próprio estado de posse é um valor EntityOwnership, uma struct baseada em flags na qual você especifica um único estado ou combina vários com um 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
}
}
O mecanismo importa mais para apps com conteúdo compartilhado: um álbum de fotos que você publicou ou compartilhou com a família deve produzir uma confirmação mais cautelosa do que um privado, e OwnershipProvidingEntity é como a entidade diz ao sistema qual é qual.9
Lote sem o custo de memória: EntityCollection
Resolver entidades não é de graça. Quando um intent recebe centenas de entidades como parâmetro, forçar o sistema a resolver cada identificador em uma instância completa durante a resolução de parâmetros pode custar tempo e memória significativos em um momento ruim. EntityCollection é a solução:11
struct EntityCollection<Entity> where Entity : AppEntity
A coleção armazena inicialmente apenas o identificador de cada entidade e oferece a opção de buscar as instâncias completas depois, caso você precise delas.11 Use-a como tipo de variável quando você guarda muitos identificadores, e use-a como tipo de parâmetro quando um intent opera sobre um 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 um parâmetro que guarda centenas de entidades, pular a resolução por identificador economiza tempo e memória exatamente quando o usuário está esperando a ação começar.11
Onde o intent roda: RunSystemShortcutIntent e IntentExecutionTargets
Duas adições menores do iOS 27 completam a superfície. RunSystemShortcutIntent é um intent exclusivo de widgets para abrir outro app ou executar um Atalho de App, um atalho personalizado ou uma ação do sistema a partir de um botão de widget:12
struct RunSystemShortcutIntent
Você o usa apenas para inicializar um Button com o inicializador de atalho do sistema e colocar esse botão em um widget; ele não faz nada útil fora desse contexto.12 Quando o usuário configura o widget, ele escolhe a ação do botão, e o intent fornece os metadados de que o sistema precisa para a interface de configuração. Ele não dá ao seu widget acesso às ações, parâmetros ou implementação de um atalho. Se o atalho escolhido precisar pedir uma entrada, o sistema pode abrir o app Atalhos para executá-lo.12
IntentExecutionTargets responde a uma pergunta que surge assim que você compartilha intents e entidades entre seu app, sua extensão de widget e sua extensão de App Intents por meio de um pacote ou framework Swift: qual processo executa o intent?13
struct IntentExecutionTargets
Por padrão, o sistema executa um intent ou query de entidade usando qualquer alvo disponível.13 Você usa IntentExecutionTargets para restringir isso. O exemplo da Apple é um navegador: adicionar um favorito pode acontecer enquanto o app não está visível, então a extensão de App Intents serve, mas abrir uma nova aba só faz sentido quando o app está visível, o que exige o próprio processo do app.13 Você declara os alvos válidos e o sistema respeita a restrição.
Caminho de adoção
Um app que já oferece App Intents acrescenta as capacidades do iOS 27 de forma incremental; nenhuma delas reescreve o modelo central.
- Encontre seu intent mais lento. Qualquer intent que faça I/O de arquivo, sincronização, inferência no dispositivo ou processamento de grandes volumes de dados é candidato a
LongRunningIntent. Adote o protocolo, mova o trabalho para dentro deperformBackgroundTask(options:operation:)e relateprogresso tempo todo. Você ganha tempo de execução além dos 30 segundos e progresso gratuito nas Live Activities.23 - Audite os identificadores das suas entidades. Se já forem estáveis entre dispositivos (UUID de servidor, nome de registro do iCloud), coloque as entidades relevantes em conformidade com
SyncableEntitye publique. Se forem por dispositivo, corrija a identidade primeiro e depois faça a conformidade.5 - Adicione
IndexedEntityQuerya queries cujas entidades sãoIndexedEntity. É puramente aditivo: os métodos só são chamados quando o sistema precisa de uma reindexação, e seus resultados de busca permanecem corretos apesar da deriva do índice.6 - Unifique parâmetros de múltiplos tipos com
@UnionValue. Em qualquer ponto onde você fingiu uma união com intents separados ou uma string discriminadora, a macro lhe dá um único parâmetro limpo.7 - Marque entidades compartilhadas com
OwnershipProvidingEntitye troque parâmetros de conjuntos grandes paraEntityCollection. O primeiro melhora a segurança da confirmação, o segundo melhora o desempenho da resolução.911
FAQ
Por quanto tempo um LongRunningIntent pode rodar em segundo plano?
A Apple documenta o piso que ele eleva, não um teto fixo. O sistema tradicionalmente dá a uma tarefa de segundo plano cerca de 30 segundos para terminar, e LongRunningIntent (via performBackgroundTask(options:operation:)) estende automaticamente essa janela além do limite padrão nas plataformas que o impõem.23 A extensão é condicional: você precisa continuar atualizando o Progress da conformidade ProgressReportingIntent, e, se parar, o sistema pode cancelar a extensão e encerrar sua tarefa mais cedo.3 Trate relatar o progresso como o preço do tempo de execução extra.
Preciso relatar progresso para usar LongRunningIntent?
Sim. LongRunningIntent é declarado como protocol LongRunningIntent : ProgressReportingIntent, então adotá-lo exige a conformidade ProgressReportingIntent e seu Progress.2 Além de satisfazer o compilador, atualizações regulares de progresso mantêm a extensão do tempo de execução em segundo plano viva e alimentam o título, o subtítulo e a barra de progresso que as Live Activities renderizam automaticamente a partir de performBackgroundTask.3
O que SyncableEntity realmente muda em tempo de execução?
Ele declara que o identificador da sua entidade é idêntico entre os dispositivos de um usuário, o que permite ao sistema tratar o objeto como uma única entidade em toda parte, em vez de objetos separados por dispositivo.5 A capacidade concreta que a Apple nomeia: a Siri pode transferir uma conversa sobre aquela entidade de um dispositivo para outro. Se seus identificadores já forem estáveis entre dispositivos, você adota o protocolo sem nenhuma outra mudança; se forem por dispositivo, você reancora a identidade em um valor estável primeiro.5
Quando o sistema chama IndexedEntityQuery?
Quando ele encontra um problema com o índice do Spotlight do seu app e o seu tipo de query adota IndexedEntityQuery (com sua entidade em conformidade com IndexedEntity).6 O sistema chama os métodos do protocolo para que você busque as entidades afetadas e as doe novamente ao Spotlight. Se sua query não adotar o protocolo, o Spotlight recorre a pedir ao seu objeto CSSearchableIndex, ou à sua CSImportExtension, se você doou por meio desse tipo.6
Por que usar EntityCollection em vez de um simples array de entidades?
EntityCollection<Entity> armazena de início apenas o identificador de cada entidade e busca as instâncias completas depois, se necessário.11 Como parâmetro de intent, ela impede o sistema de forçar cada identificador a resolver em uma instância completa durante a resolução de parâmetros, o que, para um parâmetro que guarda centenas de entidades, economiza tempo e memória em um momento potencialmente crítico.11 Um simples array [Entity] resolve tudo de forma ansiosa.
RunSystemShortcutIntent é utilizável fora de widgets?
Não. Ele existe apenas para inicializar um Button com o inicializador de atalho do sistema para colocação em um widget, e não oferece nenhuma funcionalidade em outros contextos.12 Ele expõe metadados para a interface de configuração do widget e representa a ação escolhida pelo usuário; ele não dá ao seu widget ou app acesso às ações, parâmetros ou implementação do atalho subjacente.12
O cluster completo do Ecossistema Apple: os App Intents tipados; as adições do iOS 26; a questão de roteamento frente às ferramentas MCP; os Foundation Models; o novo controle de chamada de ferramentas dos Foundation Models; a distinção entre LLM de tempo de execução e LLM de ferramental; as três superfícies; o padrão de fonte única da verdade; os servidores MCP ao lado de um app; as Live Activities; o tempo de execução do watchOS; os internos do SwiftUI; a disciplina de schema do SwiftData; os padrões do Liquid Glass; a publicação multiplataforma; a matriz de plataformas; o framework Vision; os internos do @Observable; a acessibilidade como plataforma. O hub está na Série Ecossistema Apple. Para um contexto mais amplo de iOS com agentes de IA, veja o guia de Desenvolvimento de Agentes iOS.
Referências
-
Documentação para Desenvolvedores da Apple: App Intents. A referência do framework cobrindo
AppIntent,AppEntity, queries, parâmetros e as adições do iOS 27. ↩ -
Documentação para Desenvolvedores da Apple:
LongRunningIntent(iOS 27.0 beta). “An interface you use to extend the background execution time of an app intent that performs a long-running task.” Declarado comoprotocol LongRunningIntent : ProgressReportingIntent; o sistema tradicionalmente dá às tarefas de segundo plano até 30 segundos. ↩↩↩↩↩↩↩ -
Documentação para Desenvolvedores da Apple:
performBackgroundTask(options:operation:)(iOS 27.0 beta). Roda uma operação em segundo plano com tempo estendido além do limite padrão de 30 segundos; exige atualizações regulares de progresso, ou o sistema pode cancelar a extensão; as Live Activities renderizam o progresso automaticamente. ↩↩↩↩↩↩↩↩↩ -
Documentação para Desenvolvedores da Apple:
LongRunningTaskOptions(iOS 27.0 beta). Opções para configurar tarefas de execução prolongada; declara requisitos adicionais de recursos, passados aperformBackgroundTask(options:operation:). ↩↩ -
Documentação para Desenvolvedores da Apple:
SyncableEntity(iOS 27.0 beta). “An interface that indicates your entity has an identifier that’s consistent across devices.” Declarado comoprotocol SyncableEntity : AppEntity; a Siri o usa para transferir uma conversa entre dispositivos. ↩↩↩↩↩↩↩↩ -
Documentação para Desenvolvedores da Apple:
IndexedEntityQuery(iOS 27.0 beta). “An interface that adds Spotlight reindexing support to your entity query.” Declarado comoprotocol IndexedEntityQuery : EntityQuery where Self.Entity : IndexedEntity. ↩↩↩↩↩↩↩ -
Documentação para Desenvolvedores da Apple:
AppUnionValue(iOS 27.0 beta). “A protocol that provides nominal type identity and metadata for union values.” Declarado comoprotocol AppUnionValue : TypeDisplayRepresentable; a conformidade é gerada pela macro@UnionValue. ↩↩↩↩↩↩ -
Documentação para Desenvolvedores da Apple:
AppUnionValueCasesProviding(iOS 27.0 beta). Declarado comoprotocol AppUnionValueCasesProviding : AppEnum; conformado automaticamente pelo enumCasesgerado pela macro@UnionValue. ↩↩↩↩ -
Documentação para Desenvolvedores da Apple:
OwnershipProvidingEntity(iOS 27.0 beta). “A type that provides the system with ownership and sharing context for an app entity.” Declarado comoprotocol OwnershipProvidingEntity : AppEntity; pede confirmação em entidades compartilhadas ou publicamente acessíveis. ↩↩↩↩↩ -
Documentação para Desenvolvedores da Apple:
EntityOwnership(iOS 27.0 beta). “A type that represents the ownership and sharing characteristics of an app entity.” Declarado comostruct EntityOwnership; baseado em flags, combinável com umOptionSet. ↩↩ -
Documentação para Desenvolvedores da Apple:
EntityCollection(iOS 27.0 beta). “An array of entity identifiers that you use to improve the efficiency of operations involving large numbers of entities.” Declarado comostruct EntityCollection<Entity> where Entity : AppEntity; armazena identificadores inicialmente e resolve as instâncias completas de forma preguiçosa. ↩↩↩↩↩↩↩ -
Documentação para Desenvolvedores da Apple:
RunSystemShortcutIntent(iOS 27.0 beta). “An app intent you use in widgets to open another app or perform an App Shortcut, custom shortcut, or system action.” Declarado comostruct RunSystemShortcutIntent; utilizável apenas para inicializar umButtonde widget. ↩↩↩↩↩↩ -
Documentação para Desenvolvedores da Apple:
IntentExecutionTargets(iOS 27.0 beta). “A set of options that describes which process performs an intent or entity query.” Declarado comostruct IntentExecutionTargets; restringe a execução ao app, à extensão de App Intents ou a qualquer alvo disponível. ↩↩↩↩ -
Apple, sessão 345 da WWDC26, “Discover new capabilities in the App Intents framework.” developer.apple.com/videos/play/wwdc2026/345. A Apple demonstra
LongRunningIntentresolvendo um intent de upload de fotos que continuava falhando dentro do limite de 30 segundos, com o framework gerenciando o ciclo de vida da tarefa de segundo plano e exibindo o progresso mais um controle de parada como uma Live Activity. ↩