SiriKit is now legacy: how to move to App Intents, step by step
Apple now calls SiriKit legacy, and the new Siri AI only works with App Intents. Here's how to move your custom intents over, one step at a time.
4 min read
For years, adding Siri to an iOS app meant SiriKit: an .intentdefinition file, an Intents extension, and three handler methods for every action. It worked, but nobody loved it.
Now look at Apple's own SiriKit page. It says the SiriKit, Intents and IntentsUI frameworks "continue to provide legacy support" for Shortcuts actions, widget configuration and most existing Siri interactions. For anything modern, including Apple Intelligence and the new Siri AI, Apple points you to App Intents.
So SiriKit isn't switched off, and your old shortcuts still run. But the new Siri won't learn anything about your app through it. Here's what that means, and how to move one intent at a time.
What actually changes for your app
App Intents has been around since iOS 16, so this isn't a brand-new framework. What changed is where Apple puts its effort.
With App Intents, your actions and data show up in Siri, Spotlight, the Shortcuts app, widgets and the Action button. And with the Siri AI Developer Preview, Siri can find custom content in your app and act on it, even across apps. Apple is very clear that Siri can only do this for actions and content an app "makes explicitly available using App Intents."
Two things to know about the preview. The API may still change, and it only works in development builds and for internal TestFlight testers, not in App Store builds yet. That's a good reason to start the move now, while it's quiet.
Step 1: let Xcode convert your intent definition
You don't have to rewrite everything by hand. Open your .intentdefinition file and use the "Convert to AppIntents" button. Xcode creates an App Intent struct for each custom intent.
Each new struct adopts CustomIntentMigratedAppIntent. This is the important part: it links the new intent to the old SiriKit one, so shortcuts and donations your users already have keep working.
struct OrderSoup: AppIntent, CustomIntentMigratedAppIntent {
static let intentClassName = "OrderSoupIntent"
static let title: LocalizedStringResource = "Order Soup"
@Parameter(title: "Soup")
var soup: SoupEntity
@Parameter(title: "Quantity", default: 1)
var quantity: Int
}intentClassName must match the class name of your old SiriKit intent. Get that wrong and old shortcuts quietly break.
Step 2: turn parameters into entities
In SiriKit, parameters were custom types you defined in the editor. In App Intents, the things people pick, like a soup, a note or a trail, become app entities. You also give each entity a query, so Siri and Shortcuts can find them.
struct SoupEntity: AppEntity {
static let typeDisplayRepresentation: TypeDisplayRepresentation = "Soup"
static let defaultQuery = SoupQuery()
let id: String
let name: String
let stock: Int
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(name)")
}
}
struct SoupQuery: EntityQuery {
func entities(for identifiers: [String]) async throws -> [SoupEntity] {
SoupMenu.shared.soups(withIDs: identifiers)
}
func suggestedEntities() async throws -> [SoupEntity] {
SoupMenu.shared.availableSoups()
}
}Fixed lists, like small, medium and large, become an AppEnum instead.
My advice: keep entities thin. They point at your real data, they don't replace it.
Step 3: move resolve, confirm and handle into perform()
This is the part that feels best. In SiriKit, every intent needed separate resolve, confirm and handle steps. In App Intents, Apple says perform() takes over all three.
func perform() async throws -> some IntentResult & ProvidesDialog {
if quantity > soup.stock {
return .result(dialog: "Sorry, only \(soup.stock) left.")
}
try await OrderService.shared.place(soup.id, quantity: quantity)
return .result(dialog: "Your \(soup.name) is on its way.")
}Checks, errors and the final answer all live in one async function. It reads like normal Swift, because it is.
Step 4: add App Shortcuts
Donations used to be how Siri learned what your app could do. With App Shortcuts, you list the phrases in code, and they're ready as soon as the app is installed. No setup screen for the user.
struct SoupShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: OrderSoup(),
phrases: ["Order soup in \(.applicationName)"],
shortTitle: "Order Soup",
systemImageName: "takeoutbag.and.cup.and.straw"
)
}
}Every phrase must include \(.applicationName). Keep phrases short and natural, the way a person would really say them.
If your action is a common one, like playing music or sending an email, check Apple's app schema domains first. Type @AppIntent(schema:) and Xcode fills in the intent for you, already shaped the way Siri expects.
My checklist
- List every SiriKit intent in your app, and note which ones people actually use.
- Convert the intent definition with Xcode, one intent at a time.
- Check every
intentClassNameagainst the old class names. - Create entities and queries for each parameter type.
- Move resolve, confirm and handle into
perform(). - Add App Shortcuts with two or three real phrases each.
- Test old shortcuts on a device that already had them, then test new phrases.
- Try the Siri AI preview with a development build or internal TestFlight.
The bottom line
SiriKit still works, and nothing breaks tomorrow. But it's now the past, and App Intents is where Siri, Spotlight and Apple Intelligence are going. Move your most-used intent first. The rest will feel easy after that.
Sources
- SiriKit — Apple Developer Documentation
- App Intents — Apple Developer Documentation
- Soup Chef with App Intents: Migrating custom intents — Apple Developer Documentation
- Siri AI Developer Preview — Apple Developer Documentation
- Code-along: Make your app available to Siri — WWDC26
Keep reading
All postsXcode 27 and iOS 27: Liquid Glass is the default, and what else to prepare
Liquid Glass, Swift 6.4, agents in Xcode, Device Hub and an Apple-silicon-only IDE. A practical checklist to get your app ready for iOS 27.
3 min read
Swift 6 strict concurrency: a calm, step-by-step migration
Swift 6 turns data races into compile errors. Here's a step-by-step way to move an existing iOS app without drowning in warnings, plus what Swift 6.2 changed.
4 min read
Swift on Android vs Kotlin Multiplatform: which one should share your code?
Swift 6.3 brought an official Swift SDK for Android. How it compares with Kotlin Multiplatform, and how to choose which one shares your app's code.
3 min read
Comments
No comments yet — start the conversation.