Julian H
Julian H

Reputation: 1859

How do I return multiple AppShortcuts for my AppShortcutsProvider

To make your iOS app automatically have Siri support (vs requiring users to add shortcuts manually), iOS16 offers App Shortcuts.

I want to specify multiple Siri App Shortcuts -- one per intent. But I got a bit stuck on this Swift syntax, I'm sure there's something simple going on.

A standard Swift snippet for adding app shortcuts is as below.

What confuses me is that appShortcuts is defined as a list of AppShortcuts ([AppShortcut]) but the initialiser is a single value (AppShortcut).

  1. I don't understand how this compiles. Is there an extension or something that messes with the return type?
  2. If I change it to return a list I get Cannot convert value of type '[AppShortcut]' to expected argument type 'AppShortcut' -- but I'm not enough of a Swift wiz to figure out why the expected argument type is indeed AppShortcut.
== AppIntents ==
...
public protocol AppShortcutsProvider {
    static var appShortcuts: [AppShortcut] { get }
}
...

== My intent ==

import AppIntents
struct AppShortcuts: AppShortcutsProvider {
  @AppShortcutsBuilder
  static var appShortcuts: [AppShortcut] {
    AppShortcut(
      intent: OrderStatusIntent(),
      phrases: ["Where is my \(.applicationName) order?",
        "\(.applicationName) order status"]
    )
  }
}

If I create a snippet in Swift Playground all works as expected. A single item in a list.

public struct AppShortcut {
    var title: String
}

public protocol AppShortcutsProvider {
    static var appShortcuts: [AppShortcut] { get }
}


struct BookShortcuts:AppShortcutsProvider {
    static var appShortcuts: [AppShortcut]{[
    AppShortcut(
        title:"one"
    )]
    }
}

print(BookShortcuts.appShortcuts)

Upvotes: 4

Views: 1980

Answers (3)

Bogdan Razvan
Bogdan Razvan

Reputation: 1724

You need to remove the , between the AppShortcuts:

@AppShortcutsBuilder static var appShortcuts: [AppShortcut] {
    AppShortcut(...) // avoid ,
    AppShortcut(...) // avoid ,
    AppShortcut(...)
}

Upvotes: 2

calm
calm

Reputation: 400

this worked for me:

import AppIntents
struct AppShortcuts: AppShortcutsProvider {
  @AppShortcutsBuilder
  static var appShortcuts: [AppShortcut] {
    AppShortcut(
      intent: OrderStatusIntent(),
      phrases: ["Where is my \(.applicationName) order?",
        "\(.applicationName) order status"],
      shortTitle: "Order Status"
    )
    AppShortcut(
      intent: OrderPriceIntent(),
      phrases: ["How much is my \(.applicationName) order?",
        "\(.applicationName) order price"],
      shortTitle: "Order Price"
    )
  }
}

Upvotes: 5

Julian H
Julian H

Reputation: 1859

And the solution: the @AppShortcutsBuilder directive is a result builder which is a cosmetic compile-time directive to remove list brackets and commas (AFAICT I see no other use for it). If someone can school me on the functional value of it, that'd be really amazing.

Learn more about result builders

Upvotes: 1

Related Questions