ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
カスタムインテントのApp Intentへの移行
既存のカスタムインテントをApp Intentに簡単に変換する方法を紹介します。インテントをSwiftに変換する方法を実演し、Appショートカットを作成してユーザーにAppの機能を見つけてもらえるようにする方法を説明します。App Intentの詳細については、WWDC22の「App Intentを使用したAppショートカットの実装」と「App Intentの詳細」をご覧ください。
リソース
関連ビデオ
WWDC22
-
ダウンロード
こんにちは Ariです 今回はカスタムインテントを App Intentに移行する方法を紹介します このビデオでは 新しいApp Intentフレームワークを 導入すべき理由 後方互換性の確保も含む 移行の仕組み そして実際にApp Intentに 変換する方法を説明します まず なぜApp Intentを 導入する必要があるのか これまでのフレームワークと どう違うのかを説明します Appleは2016年にSiriKit Intent フレームワークを導入しました これには メッセージング ワークアウト 電話などの 一般的なユースケースに対して 完全なユーザー体験を提供する 目的主導型のシステムインテントの セットが含まれています その後 あらゆるユースケースに 独自のインテントを定義して Appの機能を Siriやショートカット 提案に組み込める カスタムインテントを導入しました そして ウィジェットの設定や予測に カスタムインテントを使用する WidgetKitを追加しました WWDC22では Appから システムにインテントを提供する Swiftネイティブの 新しいフレームワーク App Intentを紹介しました App Intentフレームワークを 導入する利点として モダンでパワフル かつユーザーにとって 使いやすい点があげられます Swiftネイティブの設計なので モダンです 最新の言語機能により 劇的に少ない量のコードで 同じ機能を実現できます また インテント定義ファイルの維持や コード生成の利用も不要になりました スニペットを軽量なSwiftUIのビューとして 提供することも可能になりました このフレームワークがパワフルなのは エンティティやクエリによって より深いユースケースが 可能になったからです Extensionを用意しなくても Appのプロセスで直接 App Intentを実行できます また ユーザーがインテントを 設定して実行する際の ユーザー体験をカスタマイズできる 新しい方法もあります また ユーザーにとって 使いやすいのも特長です 設定の手間は一切不要で インテントをすぐに使用できる Appショートカットとして 簡単に提供できます また ショートカットが Spotlightのトップや Appに含められる Siriのヒントに表示されるため 新たな方法でユーザーに 見つけてもらうことができます 新しいフレームワークの メリットをすべて活用するには Siriとショートカット用に 構築したカスタムインテントを App Intentに アップグレードする必要があります SiriKit Intentも引き続き 完全にサポートされるため メッセージングやメディアといった Siriの領域用に構築している場合や WidgetKitでインテントを 使用する場合は そのままにしておいてください App Intentフレームワークの 詳細については WWDC22のセッション 「App Intentの詳細」を ご覧ください また Appの機能を SiriやSpotlightから とても簡単に使えるようにする Appショートカットについては 「App Intentによる Appショートカットの実装」をご覧ください 次に 移行について説明します 移行作業では Xcode上で ワンクリックするだけで 既存のインテント定義を App Intentに変換できます 同じAppバイナリでiOS 15と iOS 16の両方に対応できます また ユーザーの既存のショートカットを 新しいApp Intentで 引き続き使用できるように することもできます インテント定義をApp Intentに 変換するには インテント定義ファイルに移動して 「Convert to App Intent」ボタン を押すだけです すると Xcodeで 古いインテント定義に相当する App Intentコードが 生成されます 次に 古いコンテンツハンドラのコードを リファクタリングすることで コードを入力します これについては 次のセクションで より詳しく説明します App Intentへのアップグレード時に Appのユーザー体験を シームレスなものにするため 古いインテントから 新しいインテントへのマッピングは システムによって 自動的に行われます その仕組みについてお話しします CustomIntentMigratedAppIntent プロトコルを使うだけで システムは新旧のインテントを どのように変換すべきかについて 十分な情報を得ることができます このプロトコルを使う場合は インテントのクラス名プロパティを 提供することになりますが これは古いカスタムインテントに 使われていたクラス名となります ほとんどの場合 これを自分で 用意する必要はありません 「Convert to App Intent」 ボタンを使った場合 結果として作られるコードには このプロトコルがすでに使われています App Intentの移行機能が 利用できるため AppをiOS 16に対応させる時まで App Intentへのアップグレードを 待つ必要はありません 実際のところ 同じAppバイナリで 新旧の両方のOSに 簡単に対応することができます そのためには 古いインテントハンドラと App Intentの両方を Appに含めます 可能な限りコードを共用できるよう 共通のビジネスロジックセットに対して 両方のインテントハンドラのセットを 組み込みます 移行したApp Intentの プロトコルを使う際 Appに両方のセットを含めると ショートカットは自動的に インテントの重複を排除します そのため iOS 15以前の ショートカットAppでは 古いインテントの実装のみが表示され iOS 16以降の場合は App Intentの実装のみが 表示されることになります 最小の配備ターゲットを iOS 16以降に 切り替えた後なら 移行済みのインテントの 古いインテントハンドラと定義を 削除しても大丈夫です もう必要ないからです 移行の際に考慮すべきことの1つは 古いインテントに依存する 既存のショートカットを 持っているユーザーがいることです ショートカットAppで作成したり Appの「Siriに追加」ボタンで 追加したりしたものです 幸い 移行した App Intentプロトコルを 使う限り そうしたショートカットは 新しいApp Intentでも 引き続き機能します ユーザーのショートカットは 新しいApp Intentを使うために 上書きされるのではなく 新旧両方のインテントで使える 共通のフォーマットが 自動的に使用されます そのためには 古いインテントと App Intentの間で スキーマに互換性が ある必要があります 互換性を持たせるには カスタムインテントと App Intentのパラメータが 同じ名前と同等の型を 持つ必要があります 変更の中には スキーマの互換性を 維持したままで 行えるものもあります 具体的には パラメータの追加や削除 既存のパラメータを 非オプショナルにすることです Xcodeでスキーマの 互換性を確認するには パラメータのリストがある 古いインテント定義ファイルを チェックします 各パラメータには 名前と型があります インスペクタパネルには インテントのクラス名を入力する フィールドもあります App Intentのコードでは インテントのクラス名が インテント定義ファイルでの クラス名と一致するようにして システムで新しいインテントが 古いインテントと同等であると みなされるようにしてください そして App Intentのコードの パラメータ名と型の互換性が 保たれるようにしてください この場合も Xcodeの 「Convert to App Intents」ボタンで スキーマの互換性が 自動的に確保されます ですから ツールを使い そこに何も変更を加えなければ 問題ない状態になるはずです 次に 実際に既存のインテントを App Intentに変換する 方法を説明します インテントの移行には 2つのステップがあります ステップ1は インテント定義ファイルの移行 そしてステップ2はコードの移行です まず インテント定義から説明します 私はスープが大好きなので スープを注文できる 「Soup Chef」というAppを サンプルにしてみました このAppには注文をするための インテントがあり どのスープをいくつ注文するか どのトッピングを追加するか 受取場所や配達場所といった パラメータがあります これをApp Intentに 変換する準備ができたので Xcodeでインテント定義ファイルに 移動して 変換ボタンを押します 次に 変換するインテントを選びます この例では1つだけです そして 新しいインテントの コードを保存する場所と どのターゲットに含めるかを選びます Appのターゲットや 追加している場合は App IntentのExtensionの ターゲットに含めることができます ここではAppのターゲットを選択し Watchのターゲットにも含めます App Intentは フレームワークの ターゲットには追加できません 次に Xcodeで生成された App Intentのコードを見てみます いくつかのファイルに分割されていて インテント定義ファイルに 含まれていたすべてのインテント 列挙型 カスタム型を それぞれ表しています ここで 古いインテント定義から 移行されたコードの いくつかの部分に着目したいと思います 新しいコードには App Intentプロトコルに準拠した orderSoupという構造体があります この構造体はiOS 16以降で 利用可能であると 記されていますね iOS 16より前のiOSに Appを配備する場合は App Intentフレームワークを 使用するすべてのコードで この注釈を使用する 必要があります インテント定義ファイルの 各パラメータは そのメタデータとともに App Intentの構造体の @Parameter宣言へと 移行されています ショートカットAppの パラメータサマリーが すべてこの parameterSummary宣言へと 移行されました 従来はパラメータ関係で 表現されていたものが ParameterSummaryの Switch Case Whenの各ステートメントで 表現できるようになりました SoupとToppingsのカスタム型が Appのエンティティになり 後から記入する必要のある TODOも含められています OrderDetailsは 一時的な Appエンティティになっています 後で参照するための 一意の識別子がないため 一過性のものとみなされます そしてOrderTypeのカスタム列挙型は AppEnumになりました 人間が判読できる名前は caseDisplayRepresentations に移行されました 最後にインテント応答の すべてのダイアログは IntentDialogのExtension へと移行されました これらのダイアログはperform メソッドに使用することができます 移行の際は 必要以上の文字列が 生成される場合があるため 「Just to confirm, you wanted \ (soup)?」 のように 古いインテントハンドラで 実際に使われていないものがあれば 遠慮なく削除してください インテント定義を移行できたので 次はインテントの処理コードを移行しましょう 自動生成されたApp Intentには perform()メソッドの プレースホルダーがあり 記述が必要であることを示す TODOがあることに注目してください では その方法を見てみましょう 古いフレームワークでは インテント定義ファイルと インテントの処理コードの セットを作成していました 新しいフレームワークでは すべてがコードで表現されます 古いインテント定義のパラメータは すでに新しいコードへと 移行されています 古いコードのresolve confirm handleのメソッドを インテントの実行時に呼び出される 単一のperformメソッドへと 統合する必要があります また カスタム型と動的オプションは エンティティやクエリへと リファクタリングする必要があります では インテント処理の各フェーズを どのように移行するかを 見ていきましょう まずはresolveです resolveフェーズでは インテントハンドラが インテントの各パラメータを検証し 必要に応じて ユーザーに値を求めます resolveメソッドの移行では 可能な限り App Intentの新しい自動解決動作を 利用する必要があります 不可能な場合は 解決ロジックを performメソッドに リファクタリングする必要があります 例をいくつか見てみましょう これは soupパラメータの 古いresolveメソッドです 旧来のインテントフレームワークで よく見られるパターンです soupパラメータを アンラップしてみましょう nilの場合は 曖昧さの解消を利用して ユーザにスープを選ぶよう求める 解決結果を返します 設定されている場合は 成功の解決結果を返し すでに指定されていたものと 同じスープを返します このような定型文は App Intentの 自動解決動作のおかげで 不要になりました これまでこの方法で解決 していたパラメータがある場合は これから説明する方法で 新しい機能を利用できます デフォルトでは 移行したパラメータは オプショナルになりますが 型を非オプショナルに 変更することで 自動解決動作を 利用することができます パラメータを非オプショナルにすると App Intentsは SoupAppEntityのクエリから 提案されたエンティティを使用して パラメータが空の場合には 自動的にユーザーに値を求めます 次に パラメータ宣言にダイアログを追加して 解決システムが値を要求したときに ユーザーに対して 「どのスープをご希望ですか?」のような 特定の質問をするようにします これを行えば もうこのパラメータに 解決コードは必要ありません これ以外のすべての種類の 解決方法については resolveの実装をperform()メソッドの 先頭に移動し 適切な新しいAPIを使用して ユーザーに確認を求めるよう APIの使用方法を変更する 必要があります たとえば 数量用の古いresolveメソッドが 数量をアンラップし 値が見つからない場合は needsValueを投げ 次に数量が 実際に購入可能なスープの 数より大きいかどうかをチェックし そうであればエラーを返すとしましょう このコードをApp Intentに移行すると 最初の部分はまったく必要なくなります なぜなら 別途 数量のパラメータを非オプショナルに するだけでよいからです 2番目の部分については 解決結果がサポートされていない 完了ハンドラを引き起こすコードを スープの在庫が足りないことを示す エラーを投げるコードに 置き換えることにします このエラーは エラーと カスタムのローカライズされた 文字列リソースの 変換可能なプロトコルに適合した 列挙型として定義する必要があります そうすることで このケースがヒットしたときに 読み上げまたは表示される ダイアログを作成できます この例のように needsValueの 結果を動的に返すコードを 使用していた場合は needsValueErrorを 投げるコードに 置き換えることができます needsValueError を投げると システムは 作成したダイアログで ユーザーに値を求め その後performメソッドを最初から 再度実行します もう1つの方法は requestValueメソッドです requestValueを使うと ユーザーに値を求めて performメソッドを 最初からやり直すことなく 継続的に実行できます requestValueメソッドに加えて requestDisambiguationメソッドや requestConfirmationメソッドを使って 従来使っていたAPIの 代わりにすることができます 次に confirmについてです confirmでは 追加の検証を行って 処理を進めるかどうかを ユーザーに確認するために 必要な情報をシステムに提供します 検証を行うには confirm メソッドにあった検証ロジックを すべてperformメソッドに 移動する必要があります ユーザーに確認を求めるための 新しいシンプルなAPIとして requestConfirmation() が用意されました この新しいAPIは 1つの メソッドを呼び出すだけです このメソッドは async/awaitを使って ユーザーが確認するまで待ってから performメソッドを続行します ユーザーがキャンセルした場合は エラーが投げられ performメソッドの実行が停止します requestConfirmation メソッドには 確認のメッセージに 影響を与えるいくつかの 引数が含まれています Siriが読み上げるか表示するダイアログ スニペットで表示されるSwiftUIのビュー 確認ボタンに使われるラベル (この場合は「Order」) ダイアログをプロンプトとして 画面上に表示するかどうかを 制御するshowPrompt引数 などです ダイアログとビューの中にある 情報が双方同じである場合は これをfalseに設定するべきです Siriがそのダイアログを 表示ではなく読み上げる際に 意味を成すようにするためです 次に handleについてです handleのリファクタリングでは コードをhandleメソッドから performメソッドに移動 するだけで構いません resolve confirm handleが 1つのメソッドで 行われるようになったので 古いhandleメソッドから いくつかの検証コードを 削除することができます たとえば handleから 古いコードをコピーした場合 オプショナルではなくなった パラメータをアンラップするための コードになるため これを削除できます performメソッドの最後では インテントの結果を返す必要があります この結果にはSiriが読み上げるダイアログや 表示するスニペットビューなど さまざまなフィールドを 含めることができます それぞれに 適切なプロトコルで performメソッドの 戻り値の型に注釈を 付ける必要があります ダイアログ用のProvidesDialogや SwiftUIのスニペットビュー用の ShowSnippetViewなどです 最後に 動的なオプションの 移行について見てみましょう パラメータの型に応じてQueryまたは DynamicOptionsProviderを 記入する必要があります Xcodeではこれらの場所に TODOが作成されるので それに記入する必要があります クエリの場合は 識別子で エンティティを返すメソッド 検索可能な場合は 文字列で返すメソッド ユーザーがショートカットAppで そのパラメータをタップした時に 表示される候補の エンティティのセットを 実装する必要があります 動的なオプションの場合は すべてのオプションをresultsメソッドで 返すだけでOKです 以上です! App Intentへの移行の説明は以上です ただし もういくつか 知っておくとよいことがあります 1つ目は Appショートカットの導入です これにより インテントを 発見してもらいやすくなり ユーザーがSiriに一言話しかけるだけで 使えるようになります UIにSiriに関するヒントを追加すると Appの機能を使うには Siriに何と話しかければよいかを ユーザーに理解してもらえます これは 従来の「Siriに追加」 ボタンの代わるものとなるはずです ユーザーのアップグレードパスを 必ずテストするようにしてください このテストは 前バージョンの Appでショートカットを作成し それが新バージョンのAppでも 正しく動作することを 確かめることで行えます また 複数のロケールで 動作するAppの場合は ローカライズのことも考慮に入れます App Intentをローカライズするには App Intentに含まれるすべての文字列を ローカライズする文字列リソースとして 作成する必要があり 対応するローカライズ可能な .stringsファイルを 作成することでローカライズできます 文字列を複数形への変換に 対応させる場合は .stringsの辞書ファイルを 使うこともできます Appショートカットをローカライズ する場合は 文字列を AppShortcuts.strings というファイルに追加し 文字列の中の変数を ${ }の表記に置き換えます これまで カスタムインテントを App Intentにアップグレードして iOS 16の新機能とApp Intentの 新しいシンプルな開発モデルがもたらす メリットをフル活用することを お勧めすることについてお伝えしました Appショートカットを追加して ユーザーがAppの機能を簡単に 発見し 利用できるようにしましょう また 優れたユーザー体験を 構築する方法について WWDC22のセッション 「Appショートカットのデザイン」 をご覧ください ご視聴ありがとうございました
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。