I am trying to add a shortcut to my little iOS app. As far as I know, the only requirements are
AppShortcutsProvider
(see e.g. App Intents Spotlight integration using Shortcuts)
My expectation is that upon running this on device, this shortcut is showing up when I search for the app's name in spotlight on iOS. This expectation is not met.
What am I missing here?
Here's my code for the AppIntent
and the AppShortcutsProvider
:
import AppIntents
struct TestIntent: AppIntent {
static var title: LocalizedStringResource = "Test Intent"
static var description: LocalizedStringResource = "Test Intent"
static var openAppWhenRun: Bool = false
@Parameter(title: "Test Parameter")
var testParameter: String?
@MainActor
func perform() async throws -> some ProvidesDialog {
guard let testParameter
else { return .result(dialog: "Please provide a valid test parameter.") }
return .result(dialog: "Test parameter is: \(testParameter).")
}
}
struct TestIntentShortcut: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: TestIntent(),
phrases: [
"Set parameter to \(\.$testParameter) in \(.applicationName)."
],
shortTitle: "Test Shortcut",
systemImageName: "questionmark.text.page"
)
}
}
I am trying to add a shortcut to my little iOS app. As far as I know, the only requirements are
AppShortcutsProvider
(see e.g. App Intents Spotlight integration using Shortcuts)
My expectation is that upon running this on device, this shortcut is showing up when I search for the app's name in spotlight on iOS. This expectation is not met.
What am I missing here?
Here's my code for the AppIntent
and the AppShortcutsProvider
:
import AppIntents
struct TestIntent: AppIntent {
static var title: LocalizedStringResource = "Test Intent"
static var description: LocalizedStringResource = "Test Intent"
static var openAppWhenRun: Bool = false
@Parameter(title: "Test Parameter")
var testParameter: String?
@MainActor
func perform() async throws -> some ProvidesDialog {
guard let testParameter
else { return .result(dialog: "Please provide a valid test parameter.") }
return .result(dialog: "Test parameter is: \(testParameter).")
}
}
struct TestIntentShortcut: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: TestIntent(),
phrases: [
"Set parameter to \(\.$testParameter) in \(.applicationName)."
],
shortTitle: "Test Shortcut",
systemImageName: "questionmark.text.page"
)
}
}
You will require to add TestIntentShortcut.updateAppShortcutParameters()
in either didFinishLaunchingWithOptions
of AppDelegate
or init
method of App
struct, whichever you are using.
Call to updateAppShortcutParameters
method is important.
As Paresh Thakor pointed out, you need to add the following line to the init()
method of your apps entry point.
If you're targeting pre-iOS 17 devices, add the #available
attribute as well.
@main
struct YourAppName: App {
init() {
if #available(iOS 17.0, *) {
TestIntentShortcut.updateAppShortcutParameters()
}
}
}
Keep in mind that
From my experience, the parameters used in an AppShortcut
phrase, must point to a limited set of options. String
does not qualify, but AppEntity
and AppEnum
does.
So in your case, change the type of “testParameter” to an AppEntity
and AppEnum
class.
testParameter
non-optional–if the parameter is not provided in the call, the shortcut will prompt the user for it – appfrosch Commented Jan 3 at 13:44