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.

Accepted Reply

@denrase: i meant to post the solution here sooner, i finally got it to work late last night. Take a look at the code below. This appears to be an issue with LocalizedStringResource and string interpolation (i think). When the DisplayRepresentation sets the title to "\(title)", it causes the resulting shortcut to have a %@ in its title. Changing it to use a LocalizedStringResource with a default value gets around the issue.

struct BookEntity: AppEntity {

    static let defaultQuery = BookQuery()
    static let typeDisplayRepresentation = TypeDisplayRepresentation(name: "Book")
 
    let id: UUID
    let title: String

    var displayRepresentation: DisplayRepresentation {
        // DisplayRepresentation(title: "\(title)") // This causes the %@ to appear in the shortcut title
        DisplayRepresentation(title: LocalizedStringResource("%@", defaultValue: String.LocalizationValue(title))) // This works
    }
}

i don't have a Localizable.strings file in my project, so using just "\(title)" should work. Will log a feedback on this issue.

Replies

I'm having the exact same issue. The shortcuts app is populated with the different options and they are executed properly, but the stirng interpolation is not working, only showing "%@" instead of the parameter. Have you found a solution to this issue or is this a bug?

@denrase: i meant to post the solution here sooner, i finally got it to work late last night. Take a look at the code below. This appears to be an issue with LocalizedStringResource and string interpolation (i think). When the DisplayRepresentation sets the title to "\(title)", it causes the resulting shortcut to have a %@ in its title. Changing it to use a LocalizedStringResource with a default value gets around the issue.

struct BookEntity: AppEntity {

    static let defaultQuery = BookQuery()
    static let typeDisplayRepresentation = TypeDisplayRepresentation(name: "Book")
 
    let id: UUID
    let title: String

    var displayRepresentation: DisplayRepresentation {
        // DisplayRepresentation(title: "\(title)") // This causes the %@ to appear in the shortcut title
        DisplayRepresentation(title: LocalizedStringResource("%@", defaultValue: String.LocalizationValue(title))) // This works
    }
}

i don't have a Localizable.strings file in my project, so using just "\(title)" should work. Will log a feedback on this issue.

Nice, thank you! I have been tinkering around with your solution and this also did work for me:

var displayRepresentation: DisplayRepresentation {
    DisplayRepresentation(stringLiteral: name)
}
  • You're right! That works too. i remember seeing that initializer and thought it required a static string. Thanks for posting back, passing in the name/title directly is much cleaner.

Add a Comment

Hi @denrase @nokey4, I am trying to create a parameterized pharase like "Search {cap} in {applicaitonName}". Siri is not able to interpret it. I could not get the issue here. Also, it throws the following error in debug console while the test app is running - [Metadata] Failed to refresh Auto Shortcut parameter entities with error: Error Domain=LinkDaemon.Schema.RuntimeError Code=2 "(null)".

struct SearchIntentShortcut: AppShortcutsProvider
 {
    static var appShortcuts: [AppShortcut] {
        AppShortcut(
            intent: SearchIntent(),
            phrases: [
                "Search \(\.$searchQuery) in \(.applicationName)"
            ])
    }
}
struct SearchIntent: AppIntent {
    static var openAppWhenRun: Bool = true
    static var title: LocalizedStringResource = "Search In TestApp"
    
    @Parameter(title: "Search Term", optionsProvider: SearchTermOptionsProvider())
    var searchQuery: SearchType?
    
    @MainActor
    func perform() async throws -> some ProvidesDialog {
        let searchTerm: SearchType
        if let searchQuery = searchQuery {
            searchTerm = searchQuery
            print(" Here is the spoken query \(searchTerm.term)")
        } else {
            searchTerm = try await $searchQuery.requestDisambiguation(
                among: SearchType.all,
              dialog: "What item would you like to search?"
            )
          }
        return .result(dialog: "Searching \(searchTerm.term) in TestApp.")
        }
}

struct SearchType: AppEntity {
    let id: Int
    let term: String
    
    static var typeDisplayRepresentation  = TypeDisplayRepresentation(stringLiteral: "Search term")
    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(title: LocalizedStringResource("%@", defaultValue: String.LocalizationValue(term)))
    }
    static var defaultQuery = SearchItems()
}

struct SearchItems: EntityQuery {
    func entities(for identifiers: [SearchType.ID]) async throws -> [SearchType] {
        return SearchType.all.filter({ identifiers.contains($0.id) })
        }

    func suggestedEntities() async throws -> [SearchType] {
        return SearchType.all
    }
}
extension SearchType {
    static let all = [
        SearchType(id: 1, term: "shirt"),
        SearchType(id: 2, term: "cap")
    ]
}
private struct SearchTermOptionsProvider: DynamicOptionsProvider {
    func results() async throws -> [SearchType] {
        SearchType.all
    }
}

@ekalaivan if you are using iOS 17, i'm afraid parametrized shortcuts and Siri are broken. Shortcuts that were working on iOS 16 - and have been since iOS 16 was released - are now broken when using Siri on iOS 17. You can say the phrase exactly as you're expected to, and Siri does understand it, but it will fail to run. There is nothing you can do but wait for the next beta to correct it (hopefully). For us, it's especially troubling as we have customers who are using our App and absolutely love the fact they can carry out many actions using Siri without ever opening the App. My hope is that this is just a beta thing and will get corrected in future betas.

@nokey4 I am using iOS 16 only. Testing in Simulator. I am seeing the meta data failure error in debug console, but that is not helping to get what is the exact issue.

@ekalaivan it's not obvious what the issue is from looking at your code. Do your shortcuts work in the Shortcuts App? i.e. are you able to run them without using Siri? The Automatic shortcuts should show up in the Shortcuts App with different permutations of search type.

if your shortcuts are working in the Shortcuts App but fail with Siri, it's hard to diagnose the root cause. Sometimes you can view a sysdiagnose and glean what may be causing the failure but outside of that, Siri is a black box. Your only recourse here is to file a Feedback.

if your shortcuts are NOT working in the Shortcuts App, here are some things you can try:

  1. Don't set an OptionsProvider. My intents don't have that (yet) and the shortcuts are able to provide options when needed using suggestedEntities(). This may not be the correct thing to do but letting you know what works on my end.

  2. Add a shortcut phrase that only has the applicationName and see if this works.

Regards,

noKey

Has anyone run into this issue? I have the same thing happening. This API seems very quirky, and the documentation isn't helpful.

My AppShortcuts appear in the Shortcuts app, but Siri will not execute them with my custom phrases. I even added "Execute Spaghetti and Meatballs," to the phrases in my AppShortcut and Siri still won't use them.

Is this not working in Siri until the app is in production? Is anyone else able to tweak the custom phrases and successfully test them?

  • The user is required to allow Siri access to your shortcuts. I do not think there is a way around this. There is a ? button available when viewing your AppShortcuts in the Shortcuts app. Tap that to turn on Siri for your shortcuts. Also, after several tries, Siri did offer to turn Siri on for my AppShortcuts. Perseverance...

Add a Comment