WWDC Quick Look 💓 By SwiftGGTeam
Implement App Shortcuts with App Intents

Implement App Shortcuts with App Intents

元の動画を見る

ハイライト

iOS 16 の App Intents フレームワークを使用すると、開発者は追加のメタデータ ファイルを必要とせずに純粋な Swift コードでアプリ ショートカットを定義でき、インストール後に Siri、Spotlight、ショートカット アプリで自動的に利用可能になります。

主要内容

以前は、ユーザーがインテントを使用するには、[Siri に追加] ボタンをクリックするか、ショートカット アプリでボタンを手動で設定する必要がありました。アプリのショートカットはこの障壁を取り除きます。アプリがインストールされるとすぐに、Siri、Spotlight、およびショートカット アプリでインテントを使用できるようになります。 (01:02)

App Intents は新しい Swift 専用フレームワークで、すべての定義は Swift ソース コードで行われ、個別のメタデータ ファイルは必要ありません。 (02:57) これにより、コード生成手順が不要、ソース コード エディタとメタデータ エディタを切り替える必要がなくなり、コード レビューが容易になり、マージ競合を解決しやすくなるなど、いくつかの利点がもたらされます。

瞑想アプリを例に挙げてみましょう。以前は、ユーザーはアプリを開いてログインし、聞きたい瞑想セッションを見つける必要がありました。アプリのショートカットを使用すると、ユーザーは「瞑想を開始」と言うだけでデフォルトのセッションを開始できます。 (02:13)

詳細

基本的なアプリの目的

インテントは実装ですAppIntentプロトコルの Swift 構造体。ヘッダーとヘッダーの 2 つだけが必要です。perform方法。 (03:44)

import AppIntents

struct StartMeditationIntent: AppIntent {
    static let title: LocalizedStringResource = "Start Meditation Session"

    func perform() async throws -> some IntentResult & ProvidesDialog {
        await MeditationService.startDefaultSession()
        return .result(dialog: "Okay, starting a meditation session.")
    }
}

キーポイント:

  • titleショートカット アプリでこのインテントを表示するために使用されます
  • perform()非同期であり、非同期操作を実行できます
  • 戻る.result(dialog:)ユーザーにフィードバックを表示する
  • アプリケーションがローカライズされている場合は、ダイアログ文字列もローカライズする必要があります

アプリのショートカットを作成する

インテントがあるだけでは十分ではなく、アプリのショートカットにパッケージ化する必要があります。成し遂げるAppShortcutsProviderプロトコル: (05:31)

import AppIntents

struct MeditationShortcuts: AppShortcutsProvider {
    static var appShortcuts: [AppShortcut] {
        AppShortcut(
            intent: StartMeditationIntent(),
            phrases: [
                "Start a \(.applicationName)",
                "Begin \(.applicationName)",
                "Meditate with \(.applicationName)",
                "Start a session with \(.applicationName)"
            ]
        )
    }
}

キーポイント:

  • 使用\(.applicationName)アプリ名をハードコーディングする代わりに、Siri はメインのアプリ名と構成された同義語を自動的に挿入します。
  • ユーザーのさまざまな言い方をカバーする複数のフレーズのバリエーションを提供します
  • アプリごとに最大 10 個のアプリ ショートカットですが、ほとんどのアプリでは数個しか必要ありません
  • フレーズはアプリでサポートされているすべての言語にローカライズする必要があります

カスタム スニペット ビュー

デフォルトでは、Siri はインテントの実行時にユニバーサル ビューを表示します。カスタム SwiftUI ビューを返して、より有益な情報を得ることができます。 (07:40)

func perform() async throws -> some ProvidesDialog & ShowsSnippetView {
    await MeditationService.startDefaultSession()

    return .result(
        dialog: "Okay, starting a meditation session.",
        view: MeditationSnippetView()
    )
}

キーポイント:

  • カスタム ビューは、ウィジェットと同じビュー テクノロジを使用する SwiftUI を使用します。
  • UI拡張機能を別途作成する必要はありません
  • ビューにはインタラクションやアニメーションを含めることはできません (ウィジェットと同じ制限)
  • カスタムUIは値確認、Intent確認、Intent完了後の3段階で表示可能

パラメータを追加する

ユーザーが特定の瞑想セッションのタイプを指定できるようにするには、パラメーターを追加する必要があります。まずパラメータの型を定義して実装します。AppEntityプロトコル: (10:09)

import AppIntents

struct MeditationSession: AppEntity {
    let id: UUID
    let name: LocalizedStringResource

    static var typeDisplayName: LocalizedStringResource = "Meditation Session"
    var displayRepresentation: AppIntents.DisplayRepresentation {
        DisplayRepresentation(title: name)
    }

    static var defaultQuery = MeditationSessionQuery()
}

次に、App Intents フレームワークが識別子に基づいてエンティティを検索できるようにクエリ プロトコルを実装します: (10:55)

struct MeditationSessionQuery: EntityQuery {
    func entities(for identifiers: [UUID]) async throws -> [MeditationSession] {
        return identifiers.compactMap { SessionManager.session(for: $0) }
    }
}

インテントにパラメータを追加します: (11:16)

struct StartMeditationIntent: AppIntent {
    @Parameter(title: "Session Type")
    var sessionType: SessionType?

    // ...
}

ユーザーに値の選択を求めるプロンプトを表示

ユーザーがパラメータ値を指定しない場合は、事前にプロンプ​​トを表示できます。 App Intents は、曖昧さ回避 (固定リストから選択)、値プロンプト (自由形式の値)、および確認 (特定の値を検証) の 3 つのプロンプト タイプをサポートします。 (12:14)

func perform() async throws -> some ProvidesDialog {
    let sessionToRun = self.session ?? try await $session.requestDisambiguation(
        among: SessionManager.allSessions,
        dialog: IntentDialog("What session would you like?")
    )

    await MeditationService.start(session: sessionToRun)
    return .result(
        dialog: "Okay, starting a \(sessionToRun.name) meditation session."
    )
}

キーポイント:

  • 使用$session.requestDisambiguationユーザーが固定リストから選択できるようにする
  • アプリのインテントはセッションごとに使用されますdisplayRepresentationリスト項目の書式設定
  • ユーザーが選択すると、選択した項目が戻ります。perform方法
  • ヒントは対話を遅くする可能性があるため、使いすぎないでください

パラメータ化されたフレーズ

「心を落ち着かせる瞑想を開始する」など、ユーザーが最初のコマンドでパラメータ値を直接指定できるようにします。これには 3 つの手順が必要です: (15:27)

最初のステップはクエリに実装することですsuggestedEntities()

struct MeditationSessionQuery: EntityQuery {
    func entities(for identifiers: [UUID]) async throws -> [MeditationSession] {
        return identifiers.compactMap { SessionManager.session(for: $0) }
    }

    func suggestedEntities() async throws -> [MeditationSession] {
        return SessionManager.allSessions
    }
}

キーポイント: このメソッドを実装する必要があります。実装しないと、パラメータ化されたフレーズが生成されません。

2 番目のステップは、モデル層で App Intents パラメータ値の変更を通知することです: (16:34)

class SessionModel {
    @Published
    var sessions: [MeditationSession] = []
    private var cancellable: AnyCancellable?

    init() {
        self.cancellable = $sessions.sink { _ in
            MeditationShortcuts.updateAppShortcutParameters()
        }
    }
}

キーポイント:

  • updateAppShortcutParameters()App Intents フレームワークによって提供されるメソッドです
  • 呼び出し後、フレームワークはエンティティ リストを再クエリし、パラメータ化されたフレーズを更新します。
  • 通常、サーバーから新しいセッションを取得した後に呼び出されます。

3 番目のステップは、アプリのショートカットにパラメータを含むフレーズを追加することです: (17:09)

struct MeditationShortcuts: AppShortcutsProvider {
    static var appShortcuts: [AppShortcut] {
        AppShortcut(
            intent: StartMeditationIntent(),
            phrases: [
                "Start a \(.applicationName)",
                "Begin \(.applicationName)",
                "Meditate with \(.applicationName)",
                "Start a \($session) session with \(.applicationName)",
                "Begin a \($session) session with \(.applicationName)",
                "Meditate on \($session) with \(.applicationName)"
            ]
        )
    }
}

キーポイント:

  • 使用\($session)インテント内の参照パラメータ
  • フレームワークはパラメータ値リストとフレーズを組み合わせてすべてのバリエーションを生成します
  • パラメータ値の表示テキストは次のものから取得されます。DisplayRepresentationtitle

見つけやすさ

アプリのショートカットは箱から出してすぐに利用できますが、ユーザーはその存在を知っておく必要があります。 (17:55)

  • Siri ヒント: アプリケーション内で適切なタイミングで表示され、SwiftUI と UIKit の両方でサポートされ、複数のスタイルがサポートされます。
  • ShortcutsLink: ショートカット アプリケーション内のこのアプリケーションのすべてのショートカットのリストにジャンプします
  • Siri アクティブ レコメンデーション: ユーザーが「ここで何ができますか?」と尋ねたときに、自動的にレコメンドします。

注記

アプリのショートカットは、アプリが最初に起動される前に実行できます。 (20:36) アプリがログインを必要とする場合、インテントは正常に失敗し、最初にユーザーにログインを求めるプロンプトが表示されます。パラメータ化されたフレーズは、アプリケーションが最初に起動してフレームワークに通知されるまで使用できないため、少なくともいくつかの非パラメータ化フレーズを保持することをお勧めします。

重要ポイント

1.高頻度操作のための設定不要の音声ポータルを追加

ユーザーがアプリ内で毎日どのようなアクションを行っているかを調べ、アプリのショートカットを使用して一文の洞察を提供します。たとえば、フィットネス アプリでは「ランニングを開始」、会計アプリでは「経費を記録」などです。実装コストは非常に低く、単一の Intent 構造体と AppShortcutsProvider により、Siri と Spotlight で機能が利用可能になります。

2.パラメータ化されたフレーズを使用して対話手順を削減します

アプリに固定のコンテンツ カテゴリ (プレイリスト、お気に入りのレストラン、頻繁に使用する部屋など) がある場合は、カテゴリ名をパラメータにして、ユーザーが「音楽を再生して」ではなく「実行中のプレイリストを再生して」と言った後、「何を再生するか」を尋ねられるようにします。成し遂げるsuggestedEntities()データが変更されたときに呼び出されますupdateAppShortcutParameters()それでおしまい。

3.アプリ内で Siri ヒントを戦略的に表示

ランダムなポップアップを表示しないでください。手動で注文した後に「次回は「注文を確認してください」と言ってください」というヒントを表示するなど、ユーザーが操作完了後にすぐに同じ操作を繰り返したい瞬間を選択します。 SwiftUI で直接使用するSiriTipView, UIKit は対応するビューを使用します。繰り返しの中断を避けるために、コールバックの終了とユーザー設定の記録をサポートします。

4.ログに記録されていないステータスに対する正常な機能低下を設計します

アプリのショートカットは、ユーザーがアプリを開いたことがない場合にトリガーされる場合があります。存在するperform()必要なステータス (ログインなど) を確認し、条件が満たされていない場合は、クラッシュしたり失敗したりせずに、ユーザーがアプリケーションを開いて設定を完了するようにガイドするフレンドリーなダイアログを返します。

関連セッション

コメント

GitHub Issues · utterances