App Intents

RSS for tag

Extend your app’s custom functionality to support system-level services, like Siri and the Shortcuts app.

Posts under App Intents tag

197 Posts

Post

Replies

Boosts

Views

Activity

Siri Intent: 'Siri, count for '
Hi, I’m developing an app, which just like Clock App, uses multiple counters. I want to speak Siri commands, such as “Siri, count for one hour”. ‘count’ is the alternative app name. My AppIntent has a parameter, and Siri understands if I say “Siri, count” and asks for duration in a separate step. It runs fine, but I can’t figure out how to run the command with the duration specified upfront, without any subsequent questions from Siri. Clock App has this functionality, so it can be done. //title //perform() @Parameter(title: "Duration") var minutes: Measurement<UnitDuration> } I have a struct ShortcutsProvider: AppShortcutsProvider, phrases accept only parameters of type AppEnum or AppEntity.
1
0
102
Jul ’25
Trouble implementing search via Siri
Hi, we're having trouble implementing search through Siri voice commands. We already did it successfully for audio playback using INPlayMediaIntentHandling. For search, none of the available ways works. Both INSearchForMediaIntentHandling and ShowInAppSearchResultsIntent never open the App in the first place. We tried various commands, but e.g. "Search for " sometimes opens the Apple Music app and sometimes shows a Google search widget. Our app is never taken into consideration for providing any results. We implemented all steps mentioned in WWDC videos and documentation (e.g. https://developer.apple.com/documentation/appintents/making-in-app-search-actions-available-to-siri-and-apple-intelligence), but nothing seems to work. We're mainly testing on iOS 18 currently. Any idea why this is not working?
0
0
58
Jul ’25
App Intents not working with Siri
This implementation works very well for spotlight and App Shortcuts, but for voice commands by Siri, they don't work. AppShortcutsProvider import AppIntents struct CustomerAppIntentProvider: AppShortcutsProvider { @AppShortcutsBuilder static var appShortcuts: [AppShortcut] { AppShortcut( intent: StoresAppIntent(), phrases: ["Mostre as lojas do (.applicationName)"], shortTitle: LocalizedStringResource("Lojas"), systemImageName: "storefront" ) } } Ex. do AppIntent import AppIntents import Foundation import Loyalty import ResourceKit struct StoresAppIntent: AppIntent { static var title: LocalizedStringResource = "Mostrar as lojas" static var description: IntentDescription? = "Este atalho mostra as lojas disponiveis no app" static var openAppWhenRun: Bool = true static var isDiscoverable: Bool = true @MainActor func perform() async throws -&gt; some IntentResult { if let url = URL(string: “app://path") { UIApplication.shared.open(url, options: [:], completionHandler: { (success) in if success { print("Opened \(url)") } else { print("Failed to open \(url)") } }) } return .result() } } Basically that's what I did Our apps are with a minimum target of iOS 17 and I tested it on an iPhone 11 with Portuguese language and Siri in Portuguese
1
0
140
Jul ’25
Ask Each Time on macOS doesn't not allow empty selection
Hello! I'm facing a strange behavior on macOS related to Ask Each Time, which works fine on iOS. I've an App Intent that declares a parameter like so: @Parameter( title: "Tags", description: "Tags to add to the link.", optionsProvider: TagsOptionsProvider() ) var tags: [String]? The TagsOptionProvider is like this: struct TagsOptionsProvider: DynamicOptionsProvider { @Dependency private var modelCoordinator: ModelCoordinator @MainActor func results() async throws -> [String] { return modelCoordinator.tags().compactMap { $0.name } } } Now, the issue comes if I create a shortcut where for the tags parameter the user selects the magic variable Ask Each Time. On iOS, when the user is presented with the selector, they can simply tap 'Done' without selecting any value (the user does not want to include any tag). The problem is that on macOS the 'Done' button is disabled if there's no selection. See both behaviors: iOS: macOS: Question: Is there a way to let macOS continue even if the user doesn't select any of the available options like on iOS? I've tried declaring the tags para meter as Optional (like on the screenshot) and non-optional, both cases show the same behavior. Environment: iOS 18.5 macOS 15.5
1
0
255
Jul ’25
AppIntent perform function is not invoked from ControlWidget
I have an AppIntent that edits an object in my app. The intent accepts an app entity as a parameter, so if you run the intent it will ask which one do you want to edit, then you select one from the list and it shows a dialog that it was edited successfully. I use this same intent in my Home Screen widget initializing it with an objectEntity. The code needs to run in the app's process, not the widget extension process, so the file is added to both targets and it conforms to ForegroundContinuableIntent, and that is supposed to ensure it always runs in the app process. This works great when run from the Shortcuts app and when involved via a button in the Home Screen widget, exactly as expected. Here is that app intent: @available(iOS 17.0, *) struct EditObjectIntent: AppIntent { static let title: LocalizedStringResource = "Edit Object" @Parameter(title: "Object", requestValueDialog: "Which object do you want to edit?", inputConnectionBehavior: .connectToPreviousIntentResult) var objectEntity: ObjectEntity init() { print("INIT") } init(objectEntity: ObjectEntity) { self.objectEntity = objectEntity } @MainActor func perform() async throws -> some IntentResult & ReturnsValue<ObjectEntity> & ProvidesDialog { // Edit the object from objectEntity.id... return .result(value: objectEntity, dialog: "Done") } } @available(iOS 17.0, *) @available(iOSApplicationExtension, unavailable) extension EditObjectIntent: ForegroundContinuableIntent { } I now want to create a ControlButton that uses this intent: struct EditObjectControlWidget: ControlWidget { var body: some ControlWidgetConfiguration { StaticControlConfiguration(kind: "EditObjectControlWidget") { ControlWidgetButton(action: EditObjectIntent()) { Label("Edit Object", systemImage: "pencil") } } } } When I add the button to Control Center and tap it (on iOS 18), init is called 3x in the app process and 2x in the widget process, yet the perform function is not invoked in either process. No error appears in console logs for the app's process, but this appears for the widget process: LaunchServices: store <private> or url <private> was nil: Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=72, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler} Attempt to map database failed: permission was denied. This attempt will not be retried. Failed to initialize client context with error Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=72, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler} What am I doing wrong here? Thanks!
1
0
130
Jul ’25
AppIntent take a photo?
Hi i'm new to swift/swiftui i want to my app shortcut to have the ability to take a photo within my AppIntent instead of having to configure a 'Take a photo' action in the Shortcuts app and then parsing that to my Appintent (for less human error). Is this possible? I read there's a protocol called CameraCaptureIntent but i think it's only used for a separate extension like for Control Center, Lock Screen, and Action buttons :(
0
0
76
Jul ’25
AppIntents EntityPropertyQuery, how does "Filter Entity where" work?
When you correctly implement EntityPropertyQuery on an AppEntity, Shortcuts will expose a "Find Entity" action that calls into entities(matching:mode:sortedBy:limit:). This is demoed in the "Dive into App Intents" session and works as expected. However, with this action, you can change the "All Entity" input to a list variable which changes the action text from "Find All Entity" to "Filter Entity where" still giving you the same filter, sort and limit options. This appears to work as expected too. But, what's unexpected is that this filter action does not appear to call any method on my AppEntity code. It doesn't call entities(matching:mode:sortedBy:limit:). One would think there would need to be a filter(entities:matching:mode:sortedBy:limit:) to implement this functionality. But Shortcut just seems to do it all on it's own. I'm mostly wondering, how is this even working? Here's some example code: import AppIntents let books = [ BookEntity(id: 0, title: "A Family Affair"), BookEntity(id: 1, title: "Atlas of the Heart"), BookEntity(id: 2, title: "Atomic Habits"), BookEntity(id: 3, title: "Memphis"), BookEntity(id: 4, title: "Run Rose Run"), BookEntity(id: 5, title: "The Maid"), BookEntity(id: 6, title: "The Match"), BookEntity(id: 7, title: "Where the Crawdads Sing"), ] struct BookEntity: AppEntity, Identifiable { static var typeDisplayRepresentation: TypeDisplayRepresentation = "Book" var displayRepresentation: DisplayRepresentation { DisplayRepresentation(title: "\(title)") } static var defaultQuery = BookQuery() var id: Int @Property(title: "Title") var title: String init(id: Int, title: String) { self.id = id self.title = title } } struct BookQuery: EntityQuery { func entities(for identifiers: [Int]) async throws -> [BookEntity] { return identifiers.map { id in books[id] } } } extension BookQuery: EntityPropertyQuery { static var properties = QueryProperties { Property(\BookEntity.$title) { EqualToComparator { str in { book in book.title == str } } ContainsComparator { str in { book in book.title.contains(str) } } } } static var sortingOptions = SortingOptions { SortableBy(\BookEntity.$title) } func entities( matching comparators: [(BookEntity) -> Bool], mode: ComparatorMode, sortedBy: [Sort<BookEntity>], limit: Int? ) async throws -> [BookEntity] { books.filter { book in comparators.allSatisfy { comparator in comparator(book) } } } } The example Shortcut first invokes entities(matching:mode:sortedBy:limit:) with comparators=[], sortedBy=[], limit=nil to fetch all Book entities. Next the filter step correctly applies the title contains filter but never calls entities(matching:mode:sortedBy:limit:) or even the body of the ContainsComparator. But the output is correctly filtered.
1
0
1.6k
Jul ’25
Surfacing time-sensitive shortcuts with AppIntents framework
I'm currently working on enhancing our app’s support for App Intents. We're aiming to suggest time-sensitive shortcuts to Spotlight and Siri — for example, proactively surfacing certain shortcut from 2 hours before some event the user has registered in their database until 2 hour after that. I’ve been reviewing the AppIntents framework documentation but haven’t found a definitive answer on whether this is currently achievable. From what we understand, the RelevantIntent and RelevantContext APIs appear to support time-based suggestions, but they seem to apply only to Widgets, not to standalone app shortcuts. Is this understanding correct, and is there a recommended approach for achieving time-sensitive shortcut suggestions outside of a Widget context? Any guidance would be greatly appreciated. Best regards,
0
0
62
Jun ’25
Xcode26 beta error: “No such module '_MediaPlayer_AppIntents’”
When I import both AppIntents and MediaPlayer in the same file, I get the error “No such module '_MediaPlayer_AppIntents’” To reproduce: Create a new project with Xcode 26 beta, selecting storyboard UI and swift language. In ViewController.swift add import AppIntents and import MediaPlayer Build Get the error: “No such module '_MediaPlayer_AppIntents’” Submitted as FB18189693
1
0
129
Jun ’25
Transfer meta data from AppIntent to main app on `continueInForeground`
Hello! I am excited to try out the new continueInForeground API with iOS 26. I was wondering, what is the suggested way to transport meta data to the main app? Before, with SiriKit intents I would use the .onContinueUserActivity() API and were able to pass a NSUserActivity from the Shortcut to the Main app. Now, with the continueInForeground() call I am not sure – what would be your suggestion? Of course, I can store some data in UserDefaults, but that feels like a workaround. Happy to get some input on this! Thanks a lot and have a great day!
0
0
131
Jun ’25
View shown by App Intent with ShowsSnippetView doesn't adapt to dark mode
I have an App Intent that conforms to ShowsSnippetView and returns a view that is shown in the Siri interface after the shortcut runs. The view simply consists of a VStack with a Text element, with no special styling. When my device is set to dark mode, the view doesn't adapt: the text is black, but the background of the Siri interface is a transparent dark gray, which makes the text almost unreadable. The text should be white in dark mode. The colorScheme environment value inside the view corresponds to light mode, even though the device is set to dark mode. This is most likely a bug in iOS.
14
0
163
Jun ’25
How to donate IndexedEntity, if required in iOS 26
In the Get to Know App Intents WWDC session, it was said New this year, you can now add Spotlight indexing keys directly on properties. Annotating properties allows Spotlight to show more relevant information to customers. When donating indexed entities, the framework will handle creating the searchable item and attribute set for you. After donating entities, they can be found in Spotlight. How do you donate indexed app entities? Making app entities available in Spotlight seems to state it's not necessary to donate entities: The system can automatically extract the keys for Spotlight indexing at compile time and store them in the App Intents metadata that Xcode generates as part of your app’s bundle. As a result, Spotlight indexing is faster and can find your app entities without launching your app, and without you having to explicitly donate the entities to Spotlight. You also don’t need to manually update or remove entities from the Spotlight index when your app’s data changes. Say I have a CarEntity. The user can create/update/delete cars at any time. What is the modern way to get cars to appear in Spotlight in iOS 26?
2
0
137
Jun ’25
Custom Intent ParameterSummary based on Widget Kind/ID
I'm trying to create two widgets, widget A and B. Currently A and B are very similar so they share the same Intent and Intent Timeline Provider. I use the Intent Configuration interface to set a parameter, in this example lets say its the background tint. On one of the widgets, widget A, I want to also set another String enum parameter (for a timescale), but I don't want this option to be there for widget B as it's not relevant. I'm aware of some of the options for configuring the ParameterSummary, but none that let me pass in or inject the "kind" string (or widget ID) of the widget that's being modified. I'll try to provide some code for examples. My Widget Definition (targeting >= iOS 17) struct WidgetA: Widget { // I'd like to access this parameter within the intent let kind: String = "WidgetA" var body: some WidgetConfiguration { AppIntentConfiguration(kind: kind, intent: WidgetIntent.self, provider: IntentTimelineProvider()) { entry in WidgetView(data: entry) } .configurationDisplayName("Widget A") .description("A widget.") .supportedFamilies([.systemMedium, .systemLarge]) } } struct WidgetB: Widget { let kind: String = "WidgetB" var body: some WidgetConfiguration { AppIntentConfiguration(kind: kind, intent: WidgetIntent.self, provider: IntentTimelineProvider()) { entry in WidgetView(data: entry) } .configurationDisplayName("Widget B") .description("B widget.") .supportedFamilies([.systemMedium, .systemLarge]) } } struct IntentTimelineProvider: AppIntentTimelineProvider { typealias Entry = WidgetIntentTimelineEntry typealias Intent = WidgetIntent ........ } struct WidgetIntent: AppIntent, WidgetConfigurationIntent { // This intent allows configuration of the widget background // This intent also allows for the widget to display interactive buttons for changing the Trend Type static var title: LocalizedStringResource = "Widget Configuration" static var description = IntentDescription("Description.") static var isDiscoverable: Bool { return false} init() {} init(trend:String) { self.trend = trend } // Used for implementing interactive Widget func perform() async throws -> some IntentResult { print("WidgetIntent perform \(trend)") #if os(iOS) WidgetState.setState(type: trend) #endif return .result() } @Parameter(title: "Trend Type", default: "Trend") var trend:String // I only want to show this parameter for Widget A and not Widget B @Parameter(title: "Trend Timescale", default: .week) var timescale: TimescaleTypeAppEnum? @Parameter(title: "Background Tint", default: BackgroundTintTypeAppEnum.none) var backgroundTint: BackgroundTintTypeAppEnum? static var parameterSummary: some ParameterSummary { // Summary("Test Info") { // \.$timescale // \.$backgroundTint // } // An example of a configurable widget parameter summary, but not based of kind/ID string When(\.$backgroundTint, .equalTo, BackgroundTintTypeAppEnum.none) { Summary("Test Info") { \.$timescale \.$backgroundTint } } otherwise : { Summary("Test Info") { \.$backgroundTint } } } } enum TimescaleTypeAppEnum: String, AppEnum { case week case fortnight static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Trend Timescale") static var caseDisplayRepresentations: [Self: DisplayRepresentation] = [ .week: "Past Week", .fortnight: "Past Fortnight" ] } enum BackgroundTintTypeAppEnum: String, AppEnum { case blue case none static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Background Tint") static var caseDisplayRepresentations: [Self: DisplayRepresentation] = [ .none: "None (Default)", .blue: "Blue" ] } I know I could achieve what I'm after by having a separate Intent and separate IntentTimelineProvider for each widget. But this all seems unnessecary for just a simple optional parameter based on what widget its configuring.... unless I'm missing the point about Intents, Widgets or something! I've done a fair bit of other searching but can't find an answer to this overall scenario. Many thanks for any help.
2
0
446
Jun ’25
How to inject parameter dependency at runtime in iOS App Intent
I am trying to create an App Intent that lets a user select a day in the itinerary of a trip. The trip has to be chosen before the days available can be displayed. When the PlanActivityIntentDemo intent is ran from the shortcuts app, the trip selected is not injected into the appropriate TripItineraryDayQueryDemo Entity Query. Is there a way to get the selected trip to be injected at run time from shortcuts app. Here's some code for illustration: // Entity Definition: import AppIntents struct ShortcutsItineraryDayEntityDemo: Identifiable, Hashable, AppEntity { typealias DefaultQuery = TripItineraryDayQueryDemo static var typeDisplayRepresentation: TypeDisplayRepresentation = "Trip Itinerary Day" var displayRepresentation: DisplayRepresentation { "Trip Day" } var id: String static var defaultQuery: DefaultQuery { TripItineraryDayQueryDemo() } init() { self.id = UUID().uuidString } } struct TripItineraryDayQueryDemo: EntityQuery { // This only works in shortcut editor but not at runtime. Why? How can I fix this issue? @IntentParameterDependency<PlanActivityIntentDemo>(\.$tripEntity) var tripEntity @IntentParameterDependency<PlanActivityIntentDemo>(\.$title) var intentTitle func entities(for identifiers: [ShortcutsItineraryDayEntityDemo.ID]) async throws -> [ShortcutsItineraryDayEntityDemo] { print("entities being called with identifiers: \(identifiers)") // This method is called when the app needs to fetch entities based on identifiers. let tripsStore = TripsStore() guard let trip = tripEntity?.tripEntity.trip, let itineraryId = trip.firstItineraryId else { print("No trip or itinerary ID can be found for the selected trip.") return [] } return [] // return empty for this demo } func suggestedEntities() async throws -> [ShortcutsItineraryDayEntityDemo] { print("suggested itinerary days being called") let tripsStore = TripsStore() guard let trip = tripEntity?.tripEntity.trip, let itineraryId = trip.firstItineraryId else { print("No trip or itinerary ID found for the selected trip.") return [] } return [] } } struct PlanActivityIntentDemo: AppIntent { static var title: LocalizedStringResource { "Plan New Activity" } // The selected trip fails to get injected when intent is run from shortcut app @Parameter(title: "Trip", description: "The trip to plan an activity for", requestValueDialog: "Which trip would you like to plan an activity for?") var tripEntity: ShortcutsTripEntity @Parameter(title: "Activity Title", description: "The title of the activity", requestValueDialog: "What do you want to do or see?") var title: String @Parameter(title: "Activity Day", description: "Activity Day") var activityDay: ShortcutsItineraryDayEntity func perform() async throws -> some ProvidesDialog { // This is a demo intent, so we won't actually perform any actions. .result(dialog: "Activity '\(title)' planned") } }
0
1
139
Jun ’25
Writing unit tests for AppIntent with a @AppDependency declared
I am trying to write a unit test for an AppIntent and override the AppDependencyManager so I can inject dependencies for the purposes of testing. When I run a test, the app crashes with: AppIntents/AppDependencyManager.swift:120: Fatal error: AppDependency of type Int.Type was not initialized prior to access. Dependency values can only be accessed inside of the intent perform flow and within types conforming to _SupportsAppDependencies unless the value of the dependency is manually set prior to access. App Intent: import AppIntents struct TestAppIntent: AppIntent { @AppDependency var count: Int static var title: LocalizedStringResource { "Test App Intent "} func perform() async throws -> some IntentResult { print("\(count)") return .result() } } extension TestAppIntent { init(dependencyManager: AppDependencyManager) { _count = AppDependency(manager: dependencyManager) } } Unit Test import Testing import AppIntents @testable import AppIntentTesting struct TestAppIntentTests { @Test("test") func test() async throws { let dependencyManager = AppDependencyManager() dependencyManager.add(dependency: 5) let appIntent = TestAppIntent(dependencyManager: dependencyManager) _ = try await appIntent.perform() } }
1
0
101
Jun ’25
Shortcut automation to make PDF
Hi! I am using the Automations in shortcuts in macOS 26 dev beta 1 and I have all my shortcuts working except this one. Why?(photo included). All the others are very similar except they do other things not make pdf. They work. Why does this one not. I tried changing the extension to .doc, or .docx instead of doc and docx I tried using if name ends in .docx I tried file filtering nothing. Any ideas? Thanks!
2
0
104
Jun ’25
WidgetKit WidgetConfigurationIntent Parameter Icons
In WatchOS 26 you can now configure Apple Watch Widgets that use AppIntents instead of having a preconfigured option via AppIntentRecommendation. This is demonstrated in the Weather Details Widget. In that, the Intent has been set up such that the options have icons for each parameter. How can I update my Intent code to offer this? struct DataPointsWidgetIntent: AppIntent, WidgetConfigurationIntent { static var title: LocalizedStringResource = "Data Points Widget Configuration" static var description = IntentDescription("Configure the individual data point display for Widgets.") static var isDiscoverable: Bool { return false} init() {} func perform() async throws -> some IntentResult { print("DataPointsWidgetIntent perform") return .result() } @Parameter(title: "Show Individual Data Points", default: true) var showDataPoints: Bool? @Parameter(title: "Trend Timescale", default: .week) var timescale: TimescaleTypeAppEnum? static var parameterSummary: some ParameterSummary { Summary("Test Info") { \.$showDataPoints \.$timescale } } } enum TimescaleTypeAppEnum: String, AppEnum { case week case fortnight static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Trend Timescale") static var caseDisplayRepresentations: [Self: DisplayRepresentation] = [ .week: "Past Week", .fortnight: "Past Fortnight" ] }
1
1
99
Jun ’25
How to initialize OpenIntent parameter when returning OpensIntent in perform
I have an app that lets you create cars. I have a CarEntity, an OpenCarIntent, and a CreateCarIntent. I want to support the Open When Run option when creating a car. I understand to do this, you just update the return type of your perform function to include & OpensIntent, then change your return value to include opensIntent: OpenCarIntent(target: carEntity). When I do this, I get a compile-time error: Cannot convert value of type 'CarEntity' to expected argument type 'IntentParameter<CarEntity>' What am I doing wrong here? struct CreateCarIntent: ForegroundContinuableIntent { static let title: LocalizedStringResource = "Create Car" @Parameter(title: "Name") var name: String @MainActor func perform() async throws -> some IntentResult & ReturnsValue<CarEntity> & OpensIntent { let managedObjectContext = PersistenceController.shared.container.viewContext let car = Car(context: managedObjectContext) car.name = name try await managedObjectContext.perform { try managedObjectContext.save() } let carEntity = CarEntity(car: car) return .result( value: carEntity, opensIntent: OpenCarIntent(target: carEntity) // FIXME: Won't compile ) } } struct OpenCarIntent: OpenIntent { static let title: LocalizedStringResource = "Open Car" @Parameter(title: "Car") var target: CarEntity @MainActor func perform() async throws -> some IntentResult { await UIApplication.shared.open(URL(string: "carapp://cars/view?id=\(target.id)")!) return .result() } }
2
0
154
Jun ’25
Use UnionValue For AppIntent Parameter
I'm currently trying to use the new @UnionValue macro. From what I understood, it allows multiple types for a parameter. I created the following enum: @UnionValue enum IntentDuration { case int(Int) case duration(Measurement<UnitDuration>) } Then, I tried to use it in the following AppIntent: struct MyIntent: AppIntent { static let title: LocalizedStringResource = "intent.title" static let description = IntentDescription("intent.description") static let openAppWhenRun: Bool = true @Parameter var duration: IntentDuration @Dependency private var appManager: AppManager @MainActor func perform() async throws -> some IntentResult { // My action return .result() } } However, I get the following error from Xcode at the @Parameter line: 'init()' is unavailable Did I wrongly understand how this works? Is there another way to accept multiple types for a parameter? I didn't manage to find any docs on this.
2
0
275
Jun ’25