🚀

【iOS 18】App Intentsの新機能

2024/06/21に公開

本記事は、WWDC24の "What’s new in App Intents" (App Intentsの新機能) というセッションを記事形式にしたものです [1]

Learn about improvements and refinements to App Intents, and discover how this framework can help you expose your app's functionality to Siri and all-new features. We'll show you how to make your entities more meaningful to the platform with the Transferable API, File Representations, new IntentFile APIs, and Spotlight Indexing, opening up powerful functionality in Siri and the Shortcuts app. Empower your intents to take people deep into your app with URL Representable Entities. Explore new techniques to model your entities and intents with new APIs for error handling and union values.
(App Intentsの改善と改良について学び、このフレームワークがあなたのアプリケーションの機能をSiriやまったく新しい機能に公開するのに役立つことを発見してください。Transferable API、File Representations、新しいIntentFile API、Spotlight Indexingを使って、エンティティをプラットフォームにとってより意味のあるものにし、Siriやショートカットアプリの強力な機能を開く方法をご紹介します。URL Representable Entitiesを使用して、アプリの奥深くへと人々を誘うインテントを強化しましょう。エラー処理とunion valuesのための新しいAPIを使って、エンティティやインテントをモデル化する新しいテクニックを探求しましょう。)
- セッション概要より

はじめに

2

App Intentsは、ショートカット、Spotlight、ウィジェット、そしてアクションボタンや新しいApple Pencil Squeezeを含む他の多くの機能を使って、あなたのアプリに素晴らしい体験をもたらすことを可能にしてきました。そして今年、App IntentsはApple Intelligenceとコントロールのためのエクスペリエンス構築の中核となります。App Intentsフレームワークは、システムがあなたのアプリのエンティティを理解し、使用するのを助ける新しい方法を提供し、App Intentsをさらに使いやすくします。今日はカバーすることがたくさんあります。

アジェンダ

  • Spotlight integration

アプリのエンティティをSpotlightにインデックス化し、Siriにコンテンツの豊富な情報を提供する方法について説明します。

  • Entities and files

アプリのエンティティを特定のタイプのコンテンツに変換したり、ドキュメントをアプリのエンティティとして直接公開したりできる。

  • Universal links

アプリのインテント・タイプをユニバーサル・リンクとして公開することで、デバイスがアプリ内の必要な場所にすぐに移動できる。

  • Developer improvements

開発者エクスペリエンスも改善され、アプリのインテントをさらに扱いやすくなりました。

10

App Intentsが初めての方は、まず "Bring your app’s core features to users with App Intents" をチェックすることをお勧めします。

https://zenn.dev/shu223/articles/corefeatures_appintents
(訳注)"Bring your app’s core features to users with App Intents" の要約記事です

Spotlight integration

Spotlightは、あなたに関連するコンテンツを見つけるのに最適な場所です。

15

Spotlightは私がよく使うアプリを把握しており、サジェストとして提供してくれる。

これらのアプリをベースに、一般的なアクションに素早くアクセスできる。

また、現在の天気や最近の検索結果も表示されるかもしれない。

16

Spotlightには、特定のメモを素早く見つけるなど、探しているものを見つけるのに役立つ強力な検索機能もある。

18

また、アプリのショートカットやトップヒットは、App Intentsを通じてアプリの便利な機能を簡単に公開することができます。

IndexedEntity

今年は、Spotlightでアプリのエンティティをインデックス化できる新しいAPIを追加し、アプリのエンティティに新しく強力なセマンティック検索をもたらします。新しいIndexedEntity プロトコルから始めましょう。

22

CSSearchableIndex は、CSSearchableItem を使用して、アプリに関する情報をSpotlightにインデックスすることができます。

CSSearchableItem には、提供する情報を拡張する属性が設定されています。

24

新しいIndexedEntity は、アプリのエンティティに検索可能なインデックスを表示する簡単な方法を提供します。これにより、エンティティの検索結果の表示やSpotlightが可能になり、Siriがエンティティの検索結果を理解しやすくなります。

26

家族と私はハイキングが大好きなので、私たちが好きなトレイルを記録するアプリを作っています。アプリを開かなくてもSpotlightでトレイルを検索できたら最高だ。これを実現するために、私のTrailEntityにインデックス化されたエンティティのサポートを追加しようと思います。

28

まず、私のTrailEntityに新しいIndexedEntity ・プロトコルへの適合性を追加する。

29

それから、CSSearchableIndexindexAppEntities を呼び出して、データ・マネージャーのすべてのTrailEntityをインデックス化する。これで完了だ。

これで、TrailEntityのコンテンツをspotlightに提供することができた。動作を見てみよう。

31

まず、アプリを立ち上げて、新しいエンティティ・インデックスのコードを実行する機会を作る。

次に、Spotlightでを検索する。

33

私のトレイルのコンテンツが検索結果として表示されていることがわかる。

34

そして、私たちのTrailEntityをパラメータとして受け入れるトレイル・インテントを開いているので、結果をタップすれば、アプリでそのトレイルに直接アクセスすることができる。

CSSearchableItemAttributeSet

IndexedEntity のデフォルトの実装では、display representation のみを使用して attribute set を収集します。

しかし、アトリビュートセットを使えば、位置情報やキーワードなど、Spotlightにとって有用なあらゆる情報を指定することができる。

AttributeSetを自分で実装することで、Spotlightにより多くの情報を提供することにしよう。

43

まず、TrailEntity にAttributeSetの実装を提供します。AttributeSetをカスタマイズして、トレイルの位置から市町村や州など、私のエンティティに関連しそうなプロパティを含め、キーワードをトレイルがサポートするアクティビティに設定します。

Spotlightにより多くの情報を提供することで、検索と理解がさらに関連性の高い結果を返すことができます。

associateAppEntity

44

また、アプリケーションが CSSearchableItem APIを介してすでにSpotlightにコンテンツをインデックスしている場合、新しい associateAppEntity メソッドを使用して、インデックスする前に AppEntity を検索可能アイテムに関連付けることができます。これにより、新しいセマンティック検索で AppEntity に関する情報を見つけることができます。

また、インデックスされたエンティティAPIのいずれかで優先順位を設定できます。値が大きいほど、その項目はより重要です。例えば、お気に入りのアイテムに、お気に入りでないアイテムよりも高い優先順位を与えることができます。

CSSearchableItem は強力な検索機能を提供しますが、コンテンツに対してアクションを起こすことはできません。アプリのエンティティにインデックスを付けることで、エンティティに関する既存の作業を活用することができ、Siriがエンティティを見つけて、フライトの詳細が記載されたEメールを見つけ、友人に転送するなどのアクションを実行できるようになります。

エンティティとファイル

Transferable AppEntity

では、エンティティをデバイスにとって意味のあるものにする方法について話そう。

AppEntity を用いて、アプリのコンセプトを定義し、exposeすることができます。

50

しかし、他のアプリはこれらの概念を理解できない。その代わりに、PDFのような、どのアプリでも理解できる標準化されたフォーマットで私のエンティティを表現することができる。

また、uniform type identifiers を使用して、ファイルやデータに型のラベルを付ける。

そのためのAPIもすでに用意されている。

56

Transferable は、共有やデータ転送のためにモデルをシリアライズおよびデシリアライズする方法を宣言的に記述する方法です。そして今、あなたのアプリのエンティティを Transferable にすることができます。

例えば、Transferable を使って、アプリのエンティティをPDF、画像、リッチテキストに変換してエクスポートすることができます。

Transferable を使えば、Siriとショートカットがアプリのエンティティを変換し、新しい値を他のアプリのインテントに渡すことができます。

58

これにより、コンテンツを添付ファイルとしてメールに渡したり、画像に変換してフォトライブラリに取り込んだりすることができる。

60

私のTrailsアプリは、私が完了したアクティビティを追跡し、アクティビティ統計の要約エンティティとして表現することができます。

他のアプリにとっても意味のあるものにしたい、

62

というわけで、Transferable のサポートを追加する。

64

私は自分のエンティティを Transferable で拡張し、statictransferRepresentation メソッドを実装します。

アクティビティ概要をリッチテキストに変換するメソッドはすでに持っている、

67

そこで、DataRepresentation を追加し、エクスポートされるコンテンツ・タイプとしてRTFまたはリッチ・テキストを指定することにする。

69
また、要約をPNGファイルとしてエクスポートする方法もあるので、PNGとしてエクスポートされた FileRepresentation を追加しておこう。

TransferRepresentation を定義する順序は重要である。忠実度の高いものから低いものへと定義する。例えば、私の型のプライベートで codable な表現は最初にあり、続いて、リッチテキスト、プレーンテキストのような非可逆フォーマットだ。

では、ショートカットで実際に見てみよう。

私はすでに、アクティビティを要約するアクションの出力を受け取り、消費カロリーのプロパティをアクティビティログのノートに追加するショートカットを持っています。

72
Summarize Activities アクションの出力を受け取り、Calories Burned プロパティを Activity Log のノートに追加するショートカットが定義されていることを表している

Transferable を実装したので、

74

出力をエンティティそのもの(訳注: ここでは Statistics )に変更したらどうなるか見てみよう。

77

ショートカットを実行すると、要約活動の結果がテキストに変換され、ノートに追加されているのがわかる。

82

そして、タイプを画像に変えてもう一度ショートカットを実行すると、私のPNG表現が代わりに使われていることがわかる。

Transferable の制限

現時点では、App Entityと組み合わせて Transferable APIを使用するには、いくつかの制限があります。

87

なぜなら、Xcodeはコンパイル時にあなたのtransferable representationを理解する必要があり、それができない場合はフィードバックを提供する。

さらに、ProxyRepresentation は、@Property 属性で AppEntity のプロパティを参照する場合にのみ使用できます。

91

つまりこの例では、name プロパティには @Property 属性があるのでそれを使うことができるが、description プロパティにはその属性がないため、使用できない。

93

Transferable についてもっと知りたければ、WWDC22で行われた講演「Meet Transferable」を強くお勧めする。

IntentFile

では、IntentFile の improvementsを用いてコンテンツにアクセスする方法について説明しよう。

Transferable でエンティティを様々なコンテンツタイプに変換する方法について説明した。

これが受信側でどのように機能するか見てみよう。

99

先に、アクティビティサマリーをノートに追加することを示した。AppendToNote のようなアプリのインテントがインテント・ファイル・パラメータを受け取ると、利用可能なコンテンツ・タイプをチェックし、必要なタイプをリクエストすることができます。

そうすると、 App Intentは、transferable representationを使用して、エンティティを要求されたコンテンツタイプに変換する。

以下は、ペンでメモする場合の例です。

102

attachment パラメータは、サポートするコンテンツのタイプを宣言しています。これにより、Siriやショートカットがコンテンツを自動的に変換できるようになります。

107

インテント・ファイルのコンテンツにアクセスするには、コンテンツを抽出するための新しいAPIの1つを使用できます。インテント・ファイルがどのようなタイプのコンテンツを表しているかを確認し、変換を行うためのURLにアクセスすることができます。

FileEntity

コンテンツを表現するもう1つの方法について説明しよう。FileEntity APIは、ドキュメントベースのアプリやファイルを管理するアプリに最適です。

110

Transferable を使うと、アプリのエンティティをファイルやデータに変換できることを説明しましたが、これはエンティティがデータベースやサーバーのオブジェクトを表している場合に最適です。

エンティティ自体がテキスト文書や画像のようなファイルである場合はどうでしょうか?このような場合、ファイルはエンティティの正規バージョンです。

写真のエンティティを持つアプリがあるとします。

115

PhotoEntity はディスク上の画像ファイルを表します。私のアプリはこのエンティティを理解し、私のアプリのインテントで使用することができます、

私のお気に入りの写真インテントのように、他のアプリが私のエンティティを理解したり、アプリのインテントで使用したりすることはできません。しかし、先ほど説明したように、他のアプリはファイルを理解し、インテント・ファイルを通してファイルにアクセスすることができます。ファイル・エンティティを使うのです、

Siriとショートカットを使えば、他のアプリからファイルに安全にアクセスすることができます。

116

例えば、他のアプリの画像回転インテントを使えば、私の写真のエンティティをバックアップしているファイルに安全にアクセスし、その場で回転させることができる。

以下に、FileEntity の実装例を示す。

120

他のアプリと同じように機能するが、サポートされているコンテンツタイプのリストを提供する必要がある。

IDはファイル・エンティティの識別子である。

以降整理中

123

ファイル・エンティティ識別子は、URLで作成することも、ファイルがまだ存在しない場合はドラフト識別子として作成することもできます。ファイル・エンティティ識別子は、URLのブックマーク・データを使用します。そのため、ファイルを移動したり名前を変更したりしても、エンティティは有効です。

124

私のアプリは、私の写真エンティティ項目をグリッドに表示します。ただ、最近追加した2つのアイテムがグリッドの一番下に表示されているのですが、向きが間違っていることに気づきました。ショートカットを使って修正します。フォト・エンティティのクエリを実行してみます、

126

今日という日付が追加された画像に対するフィルタリング、

129

そして、組み込みのショートカット回転アクションを使って、クエリの結果に90度の回転を適用します。ショートカットを実行すると

130

私のアプリでは画像ファイルを回転させることができました。アプリに戻ると

131

ファイルの変更がUIアップデートで検出されたことがわかる。

132

これらの新しいAPIは、あなたのエンティティが他のアプリに意味を持たせ、他のアプリのエンティティがあなたのエンティティに意味を持たせることで、Siriやショートカットの新たな可能性を切り開く強力なものだ。

ユニバーサルリンク

次に、ユニバーサルリンクと、それをアプリのインテント・タイプでどのように表現できるかについて説明しましょう。

136

ユニバーサルリンクは、アプリがインストールされているかどうかに関わらず、ユーザーがコンテンツにアクセスするのに役立ちます。My Trailsアプリは、特定のトレイルへのユニバーサルリンクを既にサポートしています。

以下(訳注:↑のスライドにあるURL)は、特定のトレイルの詳細にリンクするURLの例です。1は開くトレイルの識別子を示しています。

138

あなたのアプリのエンティティ、列挙型、インテントをURLを持つrepresentationとして表現できるようになりました。

これにより、Siriとショートカットがそれらを特定のコンテンツへのリンクのように扱うことができるようになり、URLを開くアクションや共有可能なアクションが可能になります。

141

Shortcutsから特定のトレイルにディープリンクできるようにしたいので、TrailEntity を拡張して、URLRepresentableEntity のサポートを追加します。

私が作成したユニバーサルリンクをテンプレートとして、statcURLRepresentation を提供します。エンティティの識別子を補間値として使っていることに注目してください。URL文字列の補間として、エンティティのIDまたは @property 属性を持つプロパティを使用できます。

TrailEntityURLRepresentableEntity をサポートしたので、これを新しい URLRepresentableIntent でどのように使用できるか見てみましょう。

TrailEntity をターゲットにした OpenIntent に準拠した OpenTrailIntent を作ってみる。

そして、URLRepresentableIntent への適合性も追加する。それで終わり。実装も実行も必要ない。App Intentsが既存のURL処理コードを呼び出してくれる。

146

このApp Intentをショートカットに使うとどうなるか見てみよう。娘と私はサイクリングが大好きなので、地域の近くにあるトレイルを見つけるショートカットを用意し、私たちが走りに行けるようにランダムなトレイルを選んでいる。でも今はトレイルの名前が表示されるだけ。

150

自分のアプリでトレイルにすぐに行けるともっといい。それでは、OpenTrailインテントを追加しましょう。ShowResultアクションの代わりにOpenTrailアクションを追加します。これでショートカットを実行すると

153

TrailEntityURLRepresentation は、トレイルの詳細へのディープリンクに使用されます。

155

App IntentsでURLを使用するもう1つの方法は、パフォーマンスから新しい OpenURLIntent を返すことです。 App IntentsがSiriやショートカットで実行されると、提供されたURLを開いて、関連するコンテンツにリンクできます。また、トレイルを作成する App Intentsがあれば、新しく作成されたトレイルエンティティでOpenURLインテントを初期化して、ショートカットがアプリを開き、新しく作成されたトレイルに直接ナビゲートできるようにすることもできます。URL representableを採用することで、 App Intentsタイプにユニバーサルリンクを簡単に提供し、既存のURL処理コードを再利用し、コンテンツへのアクセスを支援することができます。

Developer improvements

今年は、開発者エクスペリエンスにもいくつかの改良を加え、App Intentsをより簡単に作成できるようにしました。新しいタイプのパラメータと、App Intentsを定義して再利用する方法の改善について説明します。

UnionValue

まずは UnionValue だ。

158

パラメータやプロパティが、いくつかの型のうちの1つで表現できることがあります。私のBuyDayPass App Intent では TrailEntity を受け取りますが、1つのトレイルまたは公園全体の1日券を購入するオプションが必要です。そのために新しいUnionValue マクロを使用します。

159

まず、列挙型を作成し、2つの購入オプションを定義する、

164

1つは公園、もう1つは小道のエンティティを取り、新しいユニオンの値マクロを列挙に追加する。

165

これで、新しいデイパスタイプの列挙を使うようにパラメーターを更新できる。

167

そして、私のperformメソッドでは、他の列挙型と同じように、pass typeパラメーターにスイッチを使うことができる。

169

列挙の各ケースは、関連する値を正確に1つ持たなければならないことに注意することが重要である。

関連する値がないケースは無効である。また、関連する値はそれぞれ明確でなければならない。

170

例えば、私はすでにTrailEntityのケースを持っているので、他のケースを追加することはできません。

UnionValue は、既存の型がいくつかあり、そのうちの1つを取りたいときに使う。これはorパラメータと考えることもできる。

Generated titles

App Intentsを使ったことがある人なら、私が書いたApp Intentsの例で、アプリ・パラメータ属性にタイトルがないことに気づいたかもしれません。

172

Xcode 16 でビルドする場合、アプリのエンティティ・プロパティやアプリのインテント・パラメータにタイトルを指定する必要がなくなりました。

173

つまり、私が提案するトレイルの意図は、このように凝縮することができる。

174

Xcodeは、構造体のプロパティ名に基づいて、タイトル文字列をインテリジェントに生成してくれます。しかし、Trail Collectionの場合は、次のようになります、

176

タイトルを注目のコレクションとして表示させたい。

177

だから、前と同じように手動でタイトルを指定する。

Framework improvements

そして最後に、フレームワークでApp Intentsを使用する方法を改善しました。

179

以前は、すべての App Intent タイプが同じモジュールになければならず、フレームワークの 1 つで定義された App Entity を使用してアプリで App Intent を持つことができませんでした。Xcode 16 では、その制限がなくなり、フレームワークで App Entity を定義し、アプリや拡張ターゲットから参照できるようになりました。

今回はフレームワークのみがサポートする。

181

フレームワーク外のライブラリーはそうではない。

183

これらは、App Intentsの素晴らしい新機能と改良点のほんの一部です。より深く知りたい方は、App Intentsのドキュメントをご覧ください。

Wrap-up

190

  • Spotlightでアプリケーションのエンティティをインデックス化し、Siriがこれまで見つけられなかったものを見つけて理解できるようにします。

  • アプリのエンティティの意味のある表現を提供し、他のアプリがコンテンツを理解できるようにします。

  • また、URL Representableやその他の新しい開発者向け改良をお試しいただき、ご意見をお聞かせください。App Intentsは、デバイス全体の他の多くの機能を強化しています。

  • App Intentsを使用した他のエキサイティングな機能のいくつかを見るには、これらの素晴らしいビデオをチェックすることをお勧めします。

脚注
  1. 個人的には動画よりも記事で読むほうがスクロールしながら読みたい部分を拾い読みできて楽なので、このような形式にしておくことにしました。 ↩︎

Discussion