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

177 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

App Shortcut "Couldn't find AppShortcutsProvider"
I am trying to create a shortcut following "Implement App Shortcuts With App Intents" talk from WWDC2022. The below is my MWE. In a standalone app, this can be extended and behave like the video. Adding this code to my main app, makes the shortcut show up within the Shortcuts app, but if I click on it, it pops up an alert saying Error Domain=LNActionForAutoShortcutPhraseFetchError Code=1 "Couldn't find AppShortcutsProvider" UserInfo={NSLocalizedDescription=Couldn't find AppShortcutsProvider} My main app has several targets, so I suppose I need to establish which one is the shortcuts provider, but I cannot find any reference to how to do this in the documents. Via Siri, the shortcut command is not recognised at all. import AppIntents import SwiftUI struct DoSomething: AppIntent {  static var title: LocalizedStringResource = "Do something"  func perform() async throws -> some IntentResult {   return .result()  }  static var openAppWhenRun: Bool = false } struct MyShortcuts: AppShortcutsProvider {  @AppShortcutsBuilder  static var appShortcuts: [AppShortcut] {   AppShortcut(    intent: DoSomething(),    phrases: ["Do Something in \(.applicationName)"],    systemImageName: "books.vertical.fill"   )  } }
5
1
2.4k
Sep ’23
AppShortcuts limit for 10 shortcuts
Hi, according this WWDC session https://developer.apple.com/wwdc22/10170 App Shortcuts are defined in Swift code, by implementing the AppShortcutsProvider protocol. To implement the protocol, I'll simply create a single getter that returns all the app shortcuts I want to set up for the user. Note that in total, your app can have a maximum of 10 app shortcuts. However, most apps only need a few. there is a limit for up to 10 AppShortcuts. Could you please clarify how that limit handled? 🤔 (e.g. project failed to build / app will crash or malfunction / only 10 shortcuts will be handled on random/ordered choice by iOS) I suppose there is some way to manage shortcuts amount but see no details at documentation yet.
5
1
2.3k
Dec ’23
App Shortcuts with parameterized phrases not working
When using just the application name in a phrase, it works great and the shortcut can be invoked via Siri: e.g. "Show books in \(.applicationName)" // This works But introducing a parameter in a phrase fails to create a working shortcut that can be invoked via Siri: e.g. "Show \(\.$book) in (\.applicationName)" // Does not work where $book is a parameter for BookEntity in my intent. i am calling updateAppShortcutParameters() and i only have a single book titled "Frankenstein". When my App is launched after a fresh install, i can see that a shortcut is automatically created in the Shortcuts App but has the following title: "Show %@ in MyAppName" Even though the title looks incorrect, tapping the shortcut works and the correct book title is passed to my Intent. However, i cannot invoke the shortcut using Siri. i.e. saying "Show Frankenstein in MyAppName" does not work. Has anyone run into this particular issue? i am running Xcode 14 Beta 6 and iOS 16 Beta 7 on my iPhone. Also tested in iOS Simulator and got the same results. This is arguably the biggest selling point for App Shortcuts (zero setup required by the user) so i am hoping it is addressed before iOS 16 becomes officially available.
9
3
3.1k
Dec ’23
How much time is AppIntent.perform() method given?
Prior to iOS 16, Intent Handlers in SiriKit only had 10 seconds to complete the request. However, i have not come across any mention of a time limit in the documentation for the new AppIntents framework. My own testing revealed this limit to be somewhere between 20-25 seconds. Does anyone know what the official time limit is to complete a request with the new AppIntents framework?
2
0
1.5k
Mar ’24
IntentDonationManager not donating Shortcuts
if #available(iOS 16.0, *) {       print("donated")       let intent = BasicIntent()       IntentDonationManager.shared.donate(intent: intent)    } Trying to test if donations work with the new App Intents framework. Donating the shortcut once a user taps a button. The shortcut is not appearing on the lock screen. Everything else is working as expected. The Shortcut is appearing in the Shortcuts App and is working via Siri. In developer settings I have Display Recent Shortcuts -> On Display Donations on Lock Screen -> On Allow Any domain -> On Allow Unverified sources -> On Running iOS 16.2, iPhone 11.
4
2
1.6k
Sep ’23
Incorrect Metadata.appintents with Xcode 14.3?
Recently (I think when updated to Xcode 14.3) my macOS Shortcut actions (implemented via AppIntent) started having a problem: When I click an action's AppEntity parameter I see the following error instead of seeing a list of entries to select from. The action “Demo Action” could not run because an internal error occurred. One difference that I notice between my builds that didn't exhibit this error and my builds that do exhibit the error: Working builds include objects.appintentsmanifest in the metadata folder Builds that break with the above behavior do not include that file Did something change in recent Xcode? What do I need to do so that Shortcuts app will run my queries again and provide popups so that I can select queried AppEnties? To recreate the problem I created a new Document Based App in Xcode 14.3 and included the following code. I then dragged "Demo Action" into a new Shortcut and clicked "Show More" and then clicked "Books: Choose". import AppIntents struct BookEntity: Identifiable, AppEntity { var id: UUID @Property(title: "Title") var title: String var displayRepresentation: DisplayRepresentation { DisplayRepresentation(title: LocalizedStringResource(stringLiteral: title)) } init(id: UUID, title: String?) { self.id = id self.title = title ?? "Unknown Title" } static var typeDisplayRepresentation: TypeDisplayRepresentation = "Book" static var defaultQuery = BookQuery() } struct BookQuery: EntityStringQuery { func entities(for identifiers: [UUID]) async throws -> [BookEntity] { library.filter { identifiers.contains($0.id) } } func entities(matching query: String) async throws -> [BookEntity] { library.filter { $0.title.localizedCaseInsensitiveContains(query) } } func suggestedEntities() async throws -> [BookEntity] { library } } struct DemoAction: AppIntent { static var title: LocalizedStringResource = "Demo Action" @Parameter(title: "Books") var books: [BookEntity] func perform() async throws -> some IntentResult { .result() } } let library: [BookEntity] = [ BookEntity(id: UUID(), title: "The Hobbit"), BookEntity(id: UUID(), title: "The Lord of the Rings"), ]
3
0
1k
Aug ’23
App Intents with OpensIntent does not work correctly
We are developing an app for iOS 16 using App Intents and Siri. We have been testing the behavior of opening another App Intent by passing the opensIntent argument to the result function in the App Intent with iOS 16.4 devices. As a result, we found that the dialog text specified in the result argument of the Intent to which it transitions is not displayed and therefore does not work. And also found that when invoked from Siri, the Intent passed to the opensIntent argument is invoked "twice". Are these behaviors bugs? Any ideas? The following is a sample code and logs. import AppIntents struct PrimaryIntent: AppIntent { static var title: LocalizedStringResource = "Primary" func perform() async throws -> some OpensIntent { print("\(String(describing: Self.self)).\(#function): invoked") return .result(opensIntent: SecondaryIntent()) } } struct SecondaryIntent: AppIntent { static var title: LocalizedStringResource = "Secondary" func perform() async throws -> some ProvidesDialog { print("\(String(describing: Self.self)).\(#function): invoked") return .result(dialog: .init(stringLiteral: "test")) } } struct ShortcutsProvider: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut(intent: PrimaryIntent(), phrases: ["\(.applicationName)"]) } } logs from Shortcut App PrimaryIntent.perform(): invoked SecondaryIntent.perform(): invoked # is not displayed dialog... logs from Siri PrimaryIntent.perform(): invoked SecondaryIntent.perform(): invoked SecondaryIntent.perform(): invoked # is not displayed dialog... # SecondaryIntent invoked twice...
1
1
1.5k
Aug ’23
Code Examples for starting background audio from an AppIntent
Hi all, I'm trying to update my app to use the AppIntent framework to play an audio file (loaded from the main bundle). I tried implementing an a PlayMusicIntent using the AudioStartingIntent protocol, but have had no luck. The intent does run, and provides the dialog response, but the music doesn't start. struct PlayMusicIntent: AudioStartingIntent { static let title:LocalizedStringResource = "Play Music" @MainActor func perform() async throws -> some IntentResult & ProvidesDialog { guard let musicPath = Bundle.main.url(forResource: "moonglow", withExtension: "mp3") else { fatalError("Could not load music file") } do { let musicPlayer = try AVAudioPlayer(contentsOf: musicPath) musicPlayer.numberOfLoops = -1 musicPlayer.play() return .result(dialog: "Now Playing Moonglow") }catch { print(error) return .result(dialog: "There was an error playing the music: \(error.localizedDescription)") } return .result(dialog: "Cannot play music") } } And then add this in my App Shortcuts Provider: AppShortcut(intent: PlayMusicIntent(), phrases: [ "Play music with \(.applicationName)" ]) I do have Audio background mode enabled. I'm thinking I need to do something with the intent's return type, but there is not a lot of documentation or online examples to implement AudioStartingIntent Any suggestions would be appreciated. Thanks, Scott
3
1
1.4k
Aug ’23
How to use ParameterSummaryBuilder?
I'm trying to put together an app intent that allows a user to navigate to a specific part of my app. I've built a basic intent, and set up an AppEnum with a case for each "screen" in my app a user should be allowed to navigate to (e.g. "All Posts", "Favourite Posts", etc.). In addition, I'd like to include additional parameters based on the enum selected. For example, I'd like to include an enum case "Post" where a user can configure a specific post to navigate to. This would mean I can have an enum of "All Posts", "Specific Post", "Favourite Posts" etc. which is cleaner than having a separate intent for "Open Specific Post"... Is this possible? I can see ParameterSummaryBuilder, AppIntent.Switch etc. but there are no docs or examples using these. Can you provide more information on whether this is possible, and show an example of Swift code to do this. Thanks!
1
0
766
Sep ’23
Siri enters loop of requesting parameter when running AppIntent
I want to add shortcut and Siri support using the new AppIntents framework. Running my intent using shortcuts or from spotlight works fine, as the touch based UI for the disambiguation is shown. However, when I ask Siri to perform this action, she gets into a loop of asking me the question to set the parameter. My AppIntent is implemented as following: struct StartSessionIntent: AppIntent { static var title: LocalizedStringResource = "start_recording" @Parameter(title: "activity", requestValueDialog: IntentDialog("which_activity")) var activity: ActivityEntity @MainActor func perform() async throws -> some IntentResult & ProvidesDialog { let activityToSelect: ActivityEntity = self.activity guard let selectedActivity = Activity[activityToSelect.name] else { return .result(dialog: "activity_not_found") } ... return .result(dialog: "recording_started \(selectedActivity.name.localized())") } } The ActivityEntity is implemented like this: struct ActivityEntity: AppEntity { static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "activity") typealias DefaultQuery = MobilityActivityQuery static var defaultQuery: MobilityActivityQuery = MobilityActivityQuery() var id: String var name: String var icon: String var displayRepresentation: DisplayRepresentation { DisplayRepresentation(title: "\(self.name.localized())", image: .init(systemName: self.icon)) } } struct MobilityActivityQuery: EntityQuery { func entities(for identifiers: [String]) async throws -> [ActivityEntity] { Activity.all()?.compactMap({ activity in identifiers.contains(where: { $0 == activity.name }) ? ActivityEntity(id: activity.name, name: activity.name, icon: activity.icon) : nil }) ?? [] } func suggestedEntities() async throws -> [ActivityEntity] { Activity.all()?.compactMap({ activity in ActivityEntity(id: activity.name, name: activity.name, icon: activity.icon) }) ?? [] } } Has anyone an idea what might be causing this and how I can fix this behavior? Thanks in advance
3
3
1k
Jun ’24
Siri Shortcuts, Sonoma, iOS 17 "No Flexible Matching Assets"
We have an app that uses Siri Shortcuts in iOS 16. WWDC '23 announced more flexible shortcut phrase matching in iOS 17 when apps are built with Xcode 15 run on Sonoma. I've downloaded and installed (Xcode and Sonoma) and rebuilt the app. I've ensured that "APP_SHORTCUTS_ENABLE_FLEXIBLE_MATCHING = YES" in the Build Settings. Unfortunately the App Shortcuts Preview Window shows the following error when I click on my build "No Flexible Matching Assets - This target is for a platform which is not supported by Flexible Matching or does not have Flexible Matching enabled" Other things I tried: I set our minimum deployment target to iOS 17 and built for an iOS 17 Simulator. Any ideas on how to get flexible matching for shortcut phrases?
5
4
948
Dec ’23
Is there any way to expose an AppIntent that lives in the app package or an AppIntentExtension to a widget?
I have AppIntent code which lives in my app package that can not easily be decoupled and migrated into its own standalone framework or extension. This is because this intent has some action that relies on my app's network and core data stack. I'd like to expose this existing intent in some way to a Button in a widget, but so far I have not had success. Is this currently possible with AppIntentPackage or some other means? Is there a way I can use AppIntents to pass a message back to the app? How should I approach this? Thank you!
6
5
2.1k
Sep ’23
iOS 17 AppIntent and requesting confirmation for widgets
I have a home widget with buttons (new in iOS 17). In order to prevent taking action if the user taps on the widget buttons accidentally, I want to ask the user for confirmation. It appeared that requestConfirmation be exactly what I needed, but no confirmation view shows up when I invoke this method in the perform function. I have tried the following: try await requestConfirmation(result: .result(dialog: "Are you sure you want to do this?") { Image(.mdlsWhite) }) and this alternative: let confirmed: Bool = try await $name.requestConfirmation(for: self.name, dialog: IntentDialog(stringLiteral: msg)) Neither option work. I am starting to think that the requestConfirmation is not to be used with Home Widgets. Is there a better way to handle confirmations for buttons included in a Home Widget?
3
1
965
Sep ’23
AppIntentsPackage protocol with SPM package not working
Hi, I am trying to integrate the new AppIntentsPackage protocol into my application. Especially what I want to do is to create a dedicate SPM package which holds all my app intents and then share that with my widget extension for Widget intents as well as the main iOS app for powering an AppShortcutProvider. Unfortunately I run into an issue here. I have the following explanatory setup: SPM package called ProjectAppIntents iOS target My AppIntents SPM package //Package: ProjectAppIntents public struct TestAppIntent: AppIntent { public static var title: LocalizedStringResource = "TestAppIntent" @Parameter(title: "Parameter1", optionsProvider: ParameterOptionProvider()) public var parameter: String public init(parameter: String) { self.parameter = parameter } public init() { } public func perform() async throws -> some IntentResult & ReturnsValue { .result(value: 5) } } struct ParameterOptionProvider: DynamicOptionsProvider { func results() async throws -> [String] { return ["Hello", "World"] } } public struct ProjectAppIntentsPackage: AppIntentsPackage { } My iOS app // Target: iOS import ProjectAppIntents struct ProjectApp: App { var body: some Scene { WindowGroup { ContentView() } } } extension ProjectApp: AppIntentsPackage { static var includedPackages: [AppIntentsPackage.Type] = [ ProjectAppIntentsPackage.self ] } struct ProjectShortcuts: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut( intent: TestAppIntent(), phrases: ["Start a \(.applicationName)"], shortTitle: "Hello World", systemImageName: "house" ) } } When I now try to compile my app, I get the following build error: 2023-06-25 09:53:47.853 appintentsnltrainingprocessor[44848:2059163] Parsing options for appintentsnltrainingprocessor 2023-06-25 09:53:47.854 appintentsnltrainingprocessor[44848:2059163] Starting AppIntents SSU YAML Generation 2023-06-25 09:53:47.868 appintentsnltrainingprocessor[44848:2059163] error: The action TestAppIntent referenced in App Shortcut does not exist Command AppIntentsSSUTraining failed with a nonzero exit code So for me it seems like the compiler cannot find the AppIntent defined in an SPM package. Am I doing something wrong here or does the AppIntentsPackage protocol not work with SPM packages ? Thanks a lot for helping !
11
3
2.8k
Oct ’23
AppShortcuts error: Command ValidateAppShortcutStringsMetadata emitted errors
In Xcode 15 beta 3 and beta 4, if you add a AppShortcuts.xcstrings catalog or legacy AppShortcuts.strings files to the project, the project will always fail to build due to the following error. error: Unable to call validation: The data couldn’t be read because it isn’t in the correct format. (in target 'LearnAppShortcuts' from project 'LearnAppShortcuts') Command ValidateAppShortcutStringsMetadata emitted errors but did not return a nonzero exit code to indicate failure The error seems related to a cli called ValidateAppShortcutStringsMetadata. Reproducing Steps (1) In Xcode 15 beta 3/4, create a new iOS app project. (2) Add an arbitrary AppIntent and AppShortcutsProvider. import AppIntents struct MyAction: AppIntent { static let title: LocalizedStringResource = "My Action" func perform() async throws -> some IntentResult { return .result() } } struct MyAppShortcts: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut(intent: MyAction(), phrases: [ "Perform action with \(.applicationName)" ], shortTitle: "Perform My Action", systemImageName: "heart") } } (3) Create a new AppShortcuts.xcstrings catalog file and add it to the iOS target (4) Build the project. The string catalog will be updated as expected. However, the build will fail.
3
0
868
Aug ’23