Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2026 App ServicesAI & Machine Learning

WWDC26 · 27 min · App Services / AI & Machine Learning

Build intelligent Siri experiences with App Schemas

Bring your app’s content and actions to Siri with App Intents. Model your data using App Entities, adopt App Schemas to enable powerful system actions, and support natural language interactions powered by Apple Intelligence. Explore how to enable semantic search, perform actions across apps, and create contextual experiences using onscreen awareness and content transfer. Find out best practices and testing tools to build fast, reliable Siri experiences.

Watch at developer.apple.com ↗

Transcript all transcripts

Chapters

  • 0:00 — Introduction
  • 1:06 — What's new in Siri
  • 4:06 — Contributing content with App Entities
  • 6:21 — Entity resolution and IndexedEntity
  • 9:49 — Making actions available
  • 12:03 — Adopting a schema domain in UnicornChat
  • 15:39 — Moving content across apps
  • 16:00 — Working across apps: onscreen awareness
  • 21:09 — Best practices
  • 24:18 — Testing your integration
  • 26:21 — Next steps

Code shown on screen · 6 snippets

Contributing message content to Apple Intelligence swift · at 7:59 ↗
// Contributing message content to Apple Intelligence
  
  @AppEntity(schema: .messages.message)
  struct MessageEntity: IndexedEntity {

      // The text content of the message
      @Property(indexingKey: \.textContent)
      var body: AttributedString?
  }
An interface that locates entities using arbitrary string input swift · at 8:36 ↗
// An interface that locates entities using arbitrary string input

  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)
      }
  }
Working across apps - View annotations swift · at 17:19 ↗
// Working across apps - View annotations
  
  List {
      ForEach(messages) { message in
          MessageRow(message: message)
              .appEntityIdentifier(
                  EntityIdentifier(
                      for: MessageEntity.self,
                      identifier: message.id
                  )
              )
      }
  }
Working across apps - Exporting content to another app swift · at 18:18 ↗
// Working across apps - Exporting content to another app
  
  extension ContactEntity: Transferable {

      static var transferRepresentation: some TransferRepresentation {
          IntentValueRepresentation(
              exporting: \.person
          )
      }
  }
Working across apps - IntentValueQuery swift · at 19:21 ↗
// Working across apps - IntentValueQuery

  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)
      }
  }
Working across apps - IntentValueRepresentation swift · at 20:00 ↗
// Working across apps - IntentValueRepresentation

  extension ContactEntity: Transferable {

      static var transferRepresentation: some TransferRepresentation {
          IntentValueRepresentation(exporting: \.person, importing: { intentPerson in                    
              let contact = Contact(importing: intentPerson)
              ContactManager.shared.contacts.append(contact)
              return contact.entity
          })
      }
  }

Resources