Developers
App Intents in iOS 27: Siri, App Schemas and the Semantic Index
How App Intents work with Siri in iOS 27: App Schemas, IndexedEntity and the semantic index, on-screen awareness and IntentValueRepresentation on iPhone Duo.
By AppleDuo EditorialPublished 7 min read
On this page
- What are App Intents in iOS 27?
- How do App Schemas and domains make Siri understand your app?
- How do I make my app's content findable by Siri?
- What if my content can't be indexed?
- How does Siri know what's on screen in my app?
- How do I share data with other apps through Siri?
- What changes for Siri on iPhone Duo?
- Key takeaways
Siri in iOS 27 can find content inside apps, act on it, and understand what's on screen. None of that happens unless your app describes itself in a way Siri can read. That description is App Intents: the same framework behind Shortcuts and Spotlight actions, extended in iOS 27 with App Schemas, the semantic index and new ways to share data between apps. This guide walks through each piece, in the order Apple recommends adopting them.
The post is based on Apple's WWDC26 sessions and documentation, a write-up by Jordan Morgan, and posts by iOS developer @sarunw. The AppleDuo team hasn't shipped this code. Several APIs are new in iOS 27 and Xcode 27, others date back to iOS 18 or iOS 26, and details can change between releases.
What are App Intents in iOS 27?
As @sarunw puts it, an App Intent is an action your app can do. Once you define it, it's available across the system: Shortcuts, Spotlight and widgets. In the WWDC26 session Build intelligent Siri experiences with App Schemas, Apple calls App Intents the foundation for integrating with Siri and Apple Intelligence.
A basic intent has a title and a perform() method. This shape has been around since iOS 16:
struct OpenInboxIntent: AppIntent {
static var title: LocalizedStringResource = "Open Inbox"
static var openAppWhenRun = true
func perform() async throws -> some IntentResult {
// Navigate to the inbox
return .result()
}
}
What's new in iOS 27 is how much further Siri can take these actions. Apple's framing is that Siri handles the language understanding while your app focuses on the action. For that split to work, Siri needs to know what each action and each piece of content means.
How do App Schemas and domains make Siri understand your app?
@sarunw sums it up in three pieces. App Intents describe the action. App Schemas give it a meaning Siri understands. Domains group the related schemas together.
Apple describes schemas as a specialization of App Intents: they're still App Intents, shaped so Siri knows how to process them. You apply one with a macro ahead of the declaration: AppIntent(schema:), AppEntity(schema:) or AppEnum(schema:). Apple's App schema domains page lists three groups:
| Domain group | Examples | Works with |
|---|---|---|
| Primary domains | Audio, Calendar, Camera, Clock, Mail, Maps, Messages, Notes, Phone, Photos, Reminders, System and in-app search | Apple Intelligence and Siri |
| Single-purpose domains | Assistant, Visual intelligence | One specific system surface |
| Shortcuts-specific domains | Books, Browser, Files, Journaling, Presentation, Reader, Spreadsheet, Whiteboard, Word processor | Shortcuts only, not Siri |
Schema domains first appeared with iOS 18. In the WWDC26 session, Apple's sample messaging app adopts the sendMessage schema from the Messages domain. Xcode 27 also checks for related schemas at build time: adopt sendMessage without draftMessage and you get a build error with a Fix-It that generates the stub.
If your content doesn't fit any schema, you can still ship plain App Intents. Jordan Morgan's iOS 27 write-up notes it isn't yet clear how much of the new Siri behavior reaches apps outside a schema.
How do I make my app's content findable by Siri?
Actions are half the story; Siri also has to find the thing a person is talking about. @sarunw lists four steps, which match the order in Apple's session:
| Step | API | Why |
|---|---|---|
| 1. Describe content | AppEntity | Says what a thing is, how it's identified, and which properties matter |
| 2. Give it a meaning | @AppEntity(schema:) | Tells Siri what kind of content it is |
| 3. Index it | IndexedEntity | Puts entities in the system semantic index |
| 4. Fall back | EntityStringQuery | Finds content you can't index ahead of time |
Steps 2 and 3 come together in one declaration. This is the message entity from Apple's WWDC26 session:
@AppEntity(schema: .messages.message)
struct MessageEntity: IndexedEntity {
// The text content of the message
@Property(indexingKey: \.textContent)
var body: AttributedString?
}
@sarunw breaks it into three decisions: the kind of content, that it belongs in the index, and which field to index. Apple says adopting IndexedEntity is the primary way to power entity resolution, because indexed entities go into the semantic index, which lets Siri match by meaning rather than exact words.
The indexingKey part is a translation. As @sarunw explains, your property is named body, but Spotlight stores its value as textContent. Without the mapping, the system has no way to know which of your fields holds the message text.
Which parts are new?
IndexedEntity arrived in iOS 18, and @Property(indexingKey:) in iOS 26, according to Apple's App Intents updates page. What iOS 27 adds is Siri using that index for semantic matching, plus new types such as IndexedEntityQuery. In the code-along session, Apple also keeps the index current by calling indexAppEntities on a CSSearchableIndex after creating or updating content, and deleteAppEntities after deleting it.
What if my content can't be indexed?
Some content can't be indexed in advance: it lives on a server, changes constantly, or is too large. For those cases Apple points to EntityStringQuery. Siri hands your app the person's words, and your app returns the matching entities. This is Apple's example:
struct ContactQuery: EntityStringQuery {
func entities(matching string: String) async throws -> [ContactEntity] {
let predicate = #Predicate<Person> { person in
person.name.localizedStandardContains(string)
}
let descriptor = FetchDescriptor<Person>(predicate: predicate)
let matches = try modelContext.fetch(descriptor)
return matches.map(\.entity)
}
}
A string query matches text, not meaning, and it runs your code on every request. Prefer IndexedEntity wherever you can and keep string queries for the rest.
How does Siri know what's on screen in my app?
@sarunw notes that in iOS 27 Siri can read what's on your screen, but you have to tell it which App Entity a view represents. Apple's article Providing contextual cues to Apple Intelligence and Siri describes two routes, and the WWDC26 session gives the rule: use a user activity when there's one primary thing on screen, and view annotations when several meaningful items are visible.
For a list, apply appEntityIdentifier(_:) to each row:
List {
ForEach(messages) { message in
MessageRow(message: message)
.appEntityIdentifier(
EntityIdentifier(
for: MessageEntity.self,
identifier: message.id
)
)
}
}
When one item fills the screen, annotate it with an NSUserActivity and set the activity's appEntityIdentifier property. In SwiftUI, the userActivity modifier gives you the activity to configure. Apple's code-along applies .userActivity with an EntityIdentifier to its event detail view but doesn't print the code, so this is our sketch:
EventDetailView(event: event)
.userActivity("com.example.viewEvent") { activity in
activity.title = event.title
activity.appEntityIdentifier = EntityIdentifier(
for: EventEntity.self,
identifier: event.id
)
}
Both APIs existed before iOS 27: Apple's documentation lists the SwiftUI modifier from iOS 18.4 and the NSUserActivity property from iOS 18.2. Apple also warns against attaching unrelated entities: an annotation should reflect the data the view shows. For custom-drawn content without one view per entity, use appEntityUIElements(_:).
How do I share data with other apps through Siri?
Transferable is the protocol behind ShareLink and drag and drop. In iOS 27, Siri uses it too. You return an IntentValueRepresentation, and one conformance covers both directions.
The reason is that plain files and data have limits. Apple's example: Maps can't use a picture of a landmark to get directions there. For people, places and names, IntentValueRepresentation (new in iOS 27) hands over a system type other apps can use directly, such as IntentPerson, PlaceDescriptor or PersonNameComponents. Exporting from Apple's session:
extension ContactEntity: Transferable {
static var transferRepresentation: some TransferRepresentation {
IntentValueRepresentation(
exporting: \.person
)
}
}
Incoming values take one of two paths. Apple's rule is to resolve content that already exists and import content that doesn't. As @sarunw describes IntentValueQuery, the system passes in the incoming value, and you look in your own data and return what matches:
struct ContactEntityQuery: IntentValueQuery {
func values(for input: [IntentPerson]) async throws -> [ContactEntity] {
let names = input.map(\.displayName)
let descriptor = FetchDescriptor<Contact>()
let contacts = try model.mainContext.fetch(descriptor)
let matches = contacts.filter { contact in
names.contains(where: { name in
contact.name.localizedStandardContains(name)
})
}
return matches.map(\.entity)
}
}
When nothing matches, create the content with IntentValueRepresentation(exporting:importing:), which takes a closure that builds a new entity from the incoming IntentPerson. IntentValueQuery itself dates from iOS 26, where it was introduced for visual intelligence.
One caution: a developer on the forums reported that on an iOS 27 beta the export closures never ran and Siri asked for clarification instead. The thread has no confirmed answer, so test on the release build.
What changes for Siri on iPhone Duo?
Nothing in the APIs. We didn't find any Siri or App Intents API specific to iPhone Duo; the code above is the same on every iPhone running iOS 27.
What changes is the canvas. When iPhone Duo is open, the inner display reports regular size classes in both directions, so many apps show a sidebar, a list and a detail view at once. Our iPhone Duo size classes guide covers that layout shift. More on screen means more for Siri to resolve with "this one" or "the third message," and more places where a missing annotation leaves Siri guessing.
A few practical checks:
- Annotate every column. If a split arrangement shows a list beside a detail view, give the list rows
appEntityIdentifierand the detail view a user activity. - Keep annotations tied to visible data. As the device folds and your layout changes, the annotations should follow the views that are actually on screen.
- Validate in stages. Apple suggests the
AppIntentsTestingframework for logic, then Shortcuts for intent shape, Spotlight for indexing, and Siri for the whole flow.
For the rest of the work of adapting an app, use our iPhone Duo readiness checklist.
Key takeaways
- App Intents describe actions; App Schemas, applied with
@AppIntent(schema:)and@AppEntity(schema:), give them a meaning Siri understands; domains group the schemas. - Make content findable in four steps: App Entity, App Schema,
IndexedEntityfor the semantic index, andEntityStringQueryas the fallback. @Property(indexingKey:)maps your field to Spotlight's, such asbodytotextContent.- For on-screen awareness, use
appEntityIdentifieron list rows andNSUserActivitywhen one item fills the screen. - Adopt
TransferablewithIntentValueRepresentation(iOS 27) to share data, andIntentValueQueryto match incoming values. - iPhone Duo uses the same APIs; its larger canvas just puts more content on screen to annotate.
Next, plan your App Store screenshots for iPhone Duo, or browse apps and games already built for the fold.
Frequently asked questions
What do I need to make my app work with Siri in iOS 27?
Define your actions as App Intents and your content as App Entities, then conform them to App Schemas from a matching domain such as Messages or Calendar. Schemas tell Siri what an intent or entity means, so you don't write training phrases.
What does IndexedEntity do for Siri?
Adopting IndexedEntity puts your app entities into the system's semantic index, which lets Siri find them by meaning rather than exact words. Apple calls it the primary way to power entity resolution.
What is @Property(indexingKey:) for?
It maps one of your entity's properties to a Spotlight attribute. For example, a message property named body can be indexed under the textContent key, so the system knows that field holds the message text.
How does Siri know what's on my app's screen?
You tell it. Apply the appEntityIdentifier modifier to each row of a list so every visible item maps to an App Entity, or attach an NSUserActivity with an appEntityIdentifier when one item fills the screen.
How do I let another app use my data through Siri?
Conform your App Entity to Transferable and return an IntentValueRepresentation that exports a system type such as IntentPerson. To accept incoming values, match them with an IntentValueQuery, or create new content with the importing variant.
Is there a Siri API specific to iPhone Duo?
Not that we found. Siri integration uses the same App Intents APIs on every iPhone. On iPhone Duo's larger inner display more content can be on screen at once, so annotating every visible item matters more.
Sources
- Build intelligent Siri experiences with App Schemas (WWDC26) · Apple Developer
- Code-along: Make your app available to Siri (WWDC26) · Apple Developer
- Providing contextual cues to Apple Intelligence and Siri · Apple Developer Documentation
- App schema domains · Apple Developer Documentation
- App Intents updates · Apple Developer Documentation
- appEntityIdentifier(_:) · Apple Developer Documentation
- iOS 27, Your App, and Siri · Swiftjective-C (Jordan Morgan)
- An App Intent is an action your app can do · @sarunw on X
- App Intents, App Schemas and domains · @sarunw on X
- Making your app's content findable by Siri, in four steps · @sarunw on X
- Three things make a message searchable by meaning · @sarunw on X
- Three decisions, one declaration · @sarunw on X
- indexingKey is a translation · @sarunw on X
- Siri can read what's on your screen in iOS 27 · @sarunw on X
- When one item fills the screen, annotate it with NSUserActivity · @sarunw on X
- In iOS 27, Siri uses Transferable too · @sarunw on X
- IntentValueQuery: match the incoming value, or create it · @sarunw on X
- Folded, iPhone Duo is an iPhone. Unfolded, it's an iPad · @sarunw on X
- Is .appEntityIdentifier + Transferable the intended way to let Siri send an on-screen image to another app? · Apple Developer Forums
Make the fold part of your app.
We showcase apps and games that do something real with iPhone Duo. Send us yours with a link to it on the App Store, or see what other developers have built.