App Schemas are predefined intent contracts that let your App Intents become directly executable by Siri via Apple Intelligence. By conforming entities and actions to schemas within a domain (e.g., Messages, Mail, Photos), Siri gains semantic understanding of your app's content and actions without requiring custom natural language handling.
⢠Siri can answer questions about your app's content, resolve entities semantically, and execute actions using natural language ā all without you writing any NLP code
⢠App Schema domains (Messages, Mail, Photos, etc.) give Siri a full end-to-end understanding of your app's capabilities through a structured contract
⢠IndexedEntity enables semantic search over your app's content so users can ask contextual questions like "Show messages from Flare about movies" and get accurate results
Demonstrates how to define an AppEntity conforming to an AppSchema, index it with IndexedEntity, and implement a sendMessage App Intent using the Messages domain schema so Siri can send messages hands-free.
import AppIntents
import Foundation
// MARK: - Contact Entity conforming to App Schema
@AssistantSchema(.messages.recipient)
struct UnicornContact: AppEntity, IndexedEntity {
static let typeDisplayRepresentation = TypeDisplayRepresentation(name: "Unicorn Contact")
static let defaultQuery = UnicornContactQuery()
let id: String
let name: String
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(name)")
}
// Properties that Siri can semantically search
@Property(title: "Name")
var indexedName: String
init(id: String, name: String) {
self.id = id
self.name = name
self.indexedName = name
}
}
struct UnicornContactQuery: EntityStringQuery {
func entities(for identifiers: [String]) async throws -> [UnicornContact] {
let all = [UnicornContact(id: "1", name: "Glow"),
UnicornContact(id: "2", name: "Flare"),
UnicornContact(id: "3", name: "Bubbles")]
return all.filter { identifiers.contains($0.id) }
}
func entities(matching string: String) async throws -> [UnicornContact] {
let all = [UnicornContact(id: "1", name: "Glow"),
UnicornContact(id: "2", name: "Flare"),
UnicornContact(id: "3", name: "Bubbles")]
return all.filter { $0.name.localizedCaseInsensitiveContains(string) }
}
}
// MARK: - Send Message Intent using Messages Domain Schema
@AssistantSchema(.messages.sendMessage)
struct SendUnicornMessageIntent: AppIntent {
static let title: LocalizedStringResource = "Send Unicorn Message"
@Parameter(title: "Recipient")
var recipient: UnicornContact
@Parameter(title: "Message Body")
var body: String
func perform() async throws -> some IntentResult & ReturnsValue<String> {
// Map schema parameters to your app's messaging logic
let confirmationMessage = "Sending '\(body)' to \(recipient.name)"
// In a real app: await UnicornChatService.send(body, to: recipient.id)
print(confirmationMessage)
return .result(value: confirmationMessage)
}
}
App Schemas are predefined ā you cannot create custom schemas. You must map your app's logic to the schema's parameter structure. IndexedEntity indexing is asynchronous and may not reflect real-time data; for frequently changing or server-side data, use EntityStringQuery instead. The domain you adopt (e.g., .messages) determines which schemas are available to implement.
Apple Intelligence features require an Apple Intelligence-capable device (iPhone 15 Pro or later, or M-series iPad/Mac). Not available in all regions at launch.
More iOS 27 APIs land every week.
Get notified when new capabilities are published ā no noise, just signal.