ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
ウィジェットへのインテリジェンスの追加
スマートスタック内のウィジェットにインテリジェンスを加える方法を確認しましょう。新しいWidget Suggestions APIをSmart Rotateを併用することで、1日を通じてより価値のあるウィジェットエクスペリエンスを提供する方法について紹介します。新しくタイムリーな情報をシステムに伝える場合や、共通のパターンをシステムに学習させる場合において、これらのAPIを採用することで、ユーザがあなたのウィジェットを発見するのを手助けし、システムがAppのコンテンツをシステムスペース表示するロジックに対して影響を与えることができます。
リソース
関連ビデオ
WWDC21
-
ダウンロード
♪ (ウィジェットへの インテリジェンスの追加) 「ウィジェットへのインテリジェンス の追加」にようこそ AppleのProactive Intelligenceチームの エンジニアのダニエルです このセッションでは ユーザーが必要とする タイミングで 現れるといった インテリジェントな体験を ウィジェットで 実現させるかについて解説します ウィジェットは色々な 場所にあります iOSのホーム画面から macOSの通知センターまで ウィジェットは ユーザーに 情報を一目で分かるように 表示します iPadOS 15で iPadのホーム画面にも ウィジェットがやってきます ウィジェットが”ホーム”と 呼べるような場所が 未だかつてない程増えました まずは ウィジェットが システムを通じて インテリジェントになると どうなるのか説明し 利用可能なAPIで 関連情報を提供し ウィジェットにインテリジェンスを もたらす方法について お話します まず ウィジェットの インテリジェンスとは何でしょうか? iPhoneやiPadでは ウィジェットはスマートスタックに まとめることができ そこでスクロールすると 様々な情報を1つの場所で 提供することができます ユーザーがスタックを編集すると ウィジェットを 追加 削除 並び替え できるだけでなく スタックの インテリジェントな動作を 見たり管理したりできます iOS 14でスマート ローテーションが導入されました スマートローテーションは システムに対して スタックに既にある ウィジェットを 正しいタイミングでスクロール させることを可能にします ウィジェットのローテーション タイミングの把握のために ウィジェットのタイムライン エントリと合わせて ウィジェットが提供する 関連シグナルが利用されます また ユーザー行動の パターンを学習し それに応じてウィジェットを ローテーションさせることもできます これはユーザーが ウィジェットに対応する 情報を閲覧する時 Appからの情報提供を 受け取ることで行われます スマートローテーションでは スタックの中に 天気やリマインダー カレンダーの ウィジェットがあるとして 天気ウィジェットは システムに 朝 私が起きるときの 提案をするようすすめます 1日の天気の概要を 伝えることができるためです 9時30分だと カレンダー ウィジェットがシステムに 午前10時に会議があると 伝えるので スタックはカレンダーへと 切り替わるでしょう 午後になると 午後3時までの リマインダーがあるので ウィジェットが スタックに リマインダーに 切り替わるように指示します 夕方になると 天気のウィジェットが 天気をまた表示するよう システムに指示します 雨が降って来たからです それで私はディナーに出るには 傘が必要だと分かります iOS 15では新機能「ウィジェットの 提案」が加わります ユーザーは全く新しい方法で ウィジェットを発見し 関連する情報を 受け取ることができます ウィジェットの提案がスマート スタックで有効化されると システムはスタックに まだ含まれていないウィジェットを 挿入することができます これは Appから明示的な 情報提供を受けることで可能になります また ウィジェットの提案は スマートローテーション と同様 システムが Appでのユーザー行動を 学習することでも実現します ウィジェットの提案が有効で 天気ウィジェットと リマインダーウィジェットしか スタックにない場合 依然としてスマートローテーション によって これらのウィジェットが 1日を通じて表示されるでしょう ただし 午前10時に 会議があって スタックにカレンダー ウィジェットがない場合 カレンダーAppが システムに 9時30分にウィジェットを 事前追加するよう指示することで 会議を忘れずに済みます ウィジェットの関連性が なくなると システムによってスタックから 削除されます 夕方のワークアウトを 完了すると システムがフィットネス ウィジェットを表示するので リングからその日の 進捗状況の 簡単な概要が 見られるようになります その後 スタックは元の状態に 戻ります 適切なタイミングでの一時的な ウィジェット挿入を Appがシステムに指示するので ユーザーがあることさえ 把握していなかった ウィジェットを 見つけられるようになります では スマートローテーションと ウィジェットの提案の 導入のために APIでシステムに 関連シグナルを提供する方法を 見ていきましょう その時 ウィジェットで 表示する可能性のある 情報を全て検討し 提案に最も一致する タイプは何か判断する 必要があります システムへの情報提供方法を 選択する際の 最終ゴールは ユーザーにとって 価値があり タイムリーで 見やすい情報を提供することです そのため ユーザーが最も 興味深いと感じる 状況をハイライトすることを 検討すべきです 例えば 天気ウィジェットでは 提案に適した状況は 気温に取るに足らない 変化があったと いうことではなく もうすぐ雨が降り出す かもしれないという 状況だと考えられるでしょう ウィジェットにおいて スマートローテーションと ウィジェットの提案を導入するには 3種類の方法があります まず Appから INRelevantShortcutをドネートし システムに対し 特定のウィジェットの提案を いつ作りだすすべきか 伝えることができます 次に ウィジェットから TimelineEntryRelevanceによって 関連スコアを提供することで スタックにウィジェットがある場合に スマートローテーションを 有効にできます 3番目は ウィジェットが 編集可能なものである場合 AppがINInteractionで configuration intentを ドネートすると システムがユーザー行動 パターンを学習し スマートローテーションと ウィジェットの提案によって そのウィジェットを推します これらAPIはそれぞれ ウィジェットの存在感を 強化するものですが 動作が若干違うので 細かく見ていきましょう まずはウィジェットの提案のための INRelevantShortcutの ドネートからです ウィジェットの構成に Intentを使うか否かを問わず Appがユーザーに ウィジェットを表示する 関連度の高い状況を検知した際に INRelevantShortcutを ドネートすることで システムは そのウィジェットが ホーム画面にまだなくても ユーザーのスタックに 挿入することが できるようになります RelevanteShortcutは 関連する時間帯を 特定することもできますし ユーザーの行動パターンに 基づいてシステムが ウィジェットを挿入するタイミングを 決定させることもできます INRelevantShortcut はstatic・intent-configuredウィジェット の両方に対応していますが ドネートは タイプごとに異なるので それぞれの導入方法を 説明していきます ウィジェットでStaticConfiguration をサポートしている場合 intentなしで 新しいINRelevantShortcutを作成し widgetKindプロパティに ウィジェットのkind文字列 を設定します これでシステムにどのAppの ウィジェットを推すべきかが伝わります その後relevanceProviders プロパティを任意で INRelevanceProvidersの 配列に設定すると ウィジェットを推すタイミングが システムに伝えられます もう少し詳しく 後ほど説明します ウィジェットがIntentConfiguration をサポートしている場合 構成に使ったIntentの インスタンスを 必要なパラメーターとともに 作成したら そのIntentを INShortcutとして渡し INRelevantShortcutを 作成します もちろん widgetkindと relevanceProvidersは Staticウィジェットと同じように 設定します RelevanteShortcutを ドネートするには デフォルトの INRelevantShortcutStore に設定するため RelevantShortcutの配列に含めます ドネートされた ショートカットの更新は Store内のRelevantShortcut の配列を新しい配列に 置き換えることで可能です つまり 以前ドネートされた RelevanteShortcutは 新しい配列から 除外することによって 無効にできるのです また Intentを含む RelevantShortcutを ドネートしてSiri文字盤の Intentを出すこともできます ウィジェットを挿入するタイミング をシステムに伝えるには INRelevanceProviders の配列を RelevantShortcut に設定します これには2つの オプションがあります まずINDateRelevanceProvider を使って 時間が決まり すでに把握している その関連性の開始・終了日を 伝えます 近日中のイベントや 速報などです 複数のproviderを 使って 1つ以上の関連する期間を 指定することもできます 次に relevance provider の空の配列を供給して ウィジェットに新しく 表示するものがあると システムに伝え その後システムが ユーザーが通常Appを 使う時間帯に基づいて 時間を選択する という方法です 他のrelevance providerも全て INRelevanceShortcutを サポートしていますが それはSiri文字盤のためであり ウィジェットの提案においては サポートされていません ではあるAppを例に 実際に導入がどのような感じかを 見ていきましょう これはCardsというAppで 全てのクレジットカード上の 取引や 残高を見ることができ 最近の購入を表示する ウィジェットが入っています INRelevanceShortcutを Appにてドネートし 最近の購入ウィジェットで ウィジェットの提案を有効化 する方法を説明します いずれかのカードで 購入が行われた直後に ウィジェットを提案する ようにしたいです ウィジェットはIntentで 構成されているので ウィジェットの提案を 可能にするには まず我々のIntentが intent定義ファイルにおいて ドネーションに対応しているか 確認します これはViewRecentPurchases Intent用のIntentエディタで 表示するクレジットカードや 購入内容を フィルターする店舗カテゴリを ウィジェットに伝えます 「Intent is edible for Siri Suggestions」が チェックされているかを 確認します これでホーム画面の ウィジェットの提案や iOSの他の場所での提案が ドネートを選択した場合に 可能になりますが これは後でINInteractions と一緒に触れます そして Intentの形成に 必要なパラメーターを 含むパラメーターの 組み合わせを作ります ウィジェットの編集には クレジットカードと 店舗カテゴリの両方がいるので カードとカテゴリ パラメーターに対応する 組み合わせが必要です これで コード内でIntentを 作れるようになりました ここではたった今 ユーザーが購入を行ったと Appに伝えられたばかりです ドネートをするには INRelevantShortcutの 空の配列を作ります 複数のショートカットを ドネートする場合に備えてです 最近の購入ウィジェット の構成に使ったIntent を初期化し 必要なパラメーターを 設定します ここではIntentで cardパラメーターを 最近の購入があったカード を参照するカードの オブジェクトに設定し categoryは カードで行われた 全ての購入を 表示できるようallに 設定したいです そしてIntentで INShortcutを作成し またそれでInRelevantShortcut を作成します shortcutRoleは ユーザーが情報を ウィジェット内で見るので .informationに設定し widgetKindを 設定します 今開始され30分または 1800秒で終わる INDateRelevanceProvider を提供すると 購入後30分たったら システムがそれを 削除できるようになります その後ショートカットを RelevantShortcutの配列に加えます 最後にデフォルトの InRelevantShortcutStoreで relevantShortcuts配列を 設定してショートカットを ドネートし エラーがあれば完了 ハンドラで処理します これで最近の購入が いつ起こっても システムはウィジェットの提案を スマートスタックに 挿入することで行えます さてTimelineEntryRelevance について説明します ウィジェットがWidgetKit にタイムラインを提供すると TimelineEntryRelevance を各タイムラインエントリに 提供することで ウィジェットの関連性を 指定することができます エントリに関連性を 付けると エントリの時間にウィジェットが スマートローテーションで どれくらい価値があるか 示唆することができます このローテーション内での価値は ウィジェットが提供する タイムラインの他のエントリに対して 相対的なものとなるので どのエントリが一番 そのユーザーに関連性があるか 決める必要が あるでしょう TimelineEntryRelevance はエントリーの日付と並ぶ TimelineEntry内の オプショナルな構造体のプロパティです relevance構造体には スコアと期間が含まれます 構造体の中のfloat型のスコアは この入力が他のに比べどれだけ 関連性が高いかを示します スコアが高くなるほど システムがローテーション する可能性が高くなります 返すスコアを決定した場合 プラスのスコアは そのタイムラインエントリが スマートローテーションに相当する エントリであることを示します ゼロのスコアはシステムに ウィジェットを ローテーションするべき ではないことを伝えます ウィジェットに 表示すべき 情報がなかったり ウィジェットをローテーション してもユーザーにメリットが ない場合などが該当します 提供されたスコアの 重要性は ウィジェットタイムラインの 他の要素に対して相対性を持ちます 関連性スコアに どんなスケーリングを使うにせよ 返すタイムラインに 一貫性があるように すべきです 少し例を見てみましょう Relevance構造体の durationでは 関連性スコアの 有効期間を指定します システムはこれを エントリの日付と共に用いて スタックをウィジェットに ローテーションする 有効なタイムフレームを 決定します 期間が終わると 今後の入力で 関連性スコアが提供されるまで システムはスコアを ゼロとして扱います 次のエントリで関連性が 提供されるまでスコアを有効と するには 期間をゼロと 指定します ではコードを 見てみましょう これは CardRecentPurchaseEntry構造体で TimelineEntryプロトコル に適合しています プロトコルによってオプショナルの relevanceプロパティが必要なため 構造体でrelevanceプロパティを 宣言します タイムラインエントリ作成時に TimelineEntryRelevanceを エントリに対し 追加することが可能です では最近の購入ウィジェット のタイムラインがどうなっているか タイムライン関連性として 提供できるスコアについて いくつか例を見て いきましょう これは最近の購入ウィジェットが 1日に返すと思われる タイムラインの例です ユーザーはより高額な 買い物を もっと気にするかも しれません 購入額規模のスコアは 費やした金額と 線形なものとして 作成することができます 今のところは関連性の 期間をゼロにしておきましょう 表示する購入内容が ないため 8時15分にゼロの スコアを返します 9時41分に52ドル60セントの 購入があったので スコアは52.6になり 同様にスコアをあてはめます グラフに表すと 私たちの買い物熱は 他のスコアと比較すると 高いことが分かりますので システムは他のエントリより このエントリに ウィジェットのローテーションを 優先させます 他のエントリにもまだ プラスのスコアがあり その時はウィジェットが ローテーションされますが 優先順位は低いでしょう また期間をゼロに 設定したので 関連性スコアは 次のタイムラインエントリで 関連性が更新されるまで 有効なままです 別のスコアリング メカニズムを 選んでみましょうか 購入額が 50ドル以上なら スコア50を それ以下なら1を 返すとします 購入が全くなければ 0を返します 食料品と買い物には 50を返し Soup Dinerや映画館 のときには1を 返します スコアグラフを見ると スコアは9時41分に 50まで上がり 6時52分までそのままです タイムラインの最高スコアは 50なので ウィジェットはこの時間帯 に表示されることが多いでしょう ウィジェットは最近の 購入を表示するので ウィジェットが過去の 買い物の情報と共に ローテーションされるのは 避けたいです では購入後30分以内で だけウィジェットを ローテーションすることを システムに許可してみましょう これはRelevance構造体上で durationプロパティを 使うことで可能です 各入力に対し 30分または1800秒の 関連性期間を設定します 関連性の期間を 30分に設定することで 入力を30分の期間中 適格にし その後のローテーションを 不適格とするよう システムに伝えることが できます これらの例では スコアは購入金額に 基づいていますが 実際には タイムライン関連性スコアは 好きなようにできます クレジットカードの 種類や 購入が行われた場所や時間 またはその他に することもできたのです 正しい方法というものは ありません INInteractionの ドネートの話をします INInteractions経由で スマートローテーションと ウィジェットの提案を の両方を有効にするには ウィジェットの構成に使った Intentを作成し ドネートします Appはユーザーが ウィジェットが表示する 情報に一致するApp内の 情報を閲覧する度に INInteractionを ドネートします 各ドネートは ユーザーが Appで情報を 閲覧する傾向がある タイミングを学習する システム行動モデル にとっての データポイントです モデルがユーザーの 次のインタラクションを 予測した際に システムはそのIntentに該当する 提案を作成します ドネートされたIntentが ウィジェットの構成に 使用したものと同じである限り システムは予測から スマートローテーションと ウィジェットの提案の 両方を 他の提案と共に 生成します INInteractionの ドネートを Cardsプロジェクトで INRelevantShortcutと 同様に行うためには Intentが提案にとって 適格であることを確認し ウィジェットの構成に 必要なパラメーター に対し対応する組み合わせを 作る必要があります ここでは最終的に システム内の 他のロケーションで ドネーションが表示された 時用の提案UIを デザインしなければなりません Cards Appでなら ユーザーがカードの 最近の購入の全てを いつ閲覧したとしても ウィジェットが表示中の情報に対し ユーザーが現在 関心を持っていることを システムが把握できるよう ウィジェットのIntentを ドネートできます まずIntentを初期化します カードのパラメーターに ユーザーが 現在閲覧中のカードを 設定し categoryをallに 設定します ユーザーが現在 このカードの 全ての取引を 閲覧しているからです 次にIntentとINInteraction を紐づけし ドネートメソッドを呼び出します これでシステムは ユーザーがApp内で このカードの最近の購入 を閲覧したことを 把握しました しばらくすると システムは ユーザーに いつ閲覧傾向があるか学習し 一致するウィジェットを 最も適したタイミングで表示します 作ったINInteractionドネーションで スマートローテーションと ウィジェットの提案を 有効化できるだけでなく システムにIntentを ロック画面やスポットライト Siriショートカット 提案ウィジェットで Siriからの提案として 表示することも可能です ウィジェットでIntent を採用していない場合でもです INInteraction のドネートで Appやオンデバイス インテリジェンスを 進化させる方法について より詳しく知るには 「インテントのドネートと Appのプレゼンスの向上」 もチェックしてみてください さて INRelevantShortcutや TimelineEntryRelecance INInteractionでは ウィジェットの スマートローテーションや ウィジェットの提案に対応できます パフォーマンスに対する考慮や システムの他の ドネーションのため ドネーションはウィジェット の表示を保証するものでは ありません しかしこれらのAPIを まとめて導入することで ウィジェットが最も 良いタイミングで 表示されるようシステムを 設定できます 開発中は 設定App内の 開発者設定にある WidgetKit開発者 モードをオンにすると ウィジェット表示の システム制限を迂回 できて便利です まとめると ウィジェットの提案は ユーザーがウィジェットを 必要とする時に ウィジェットを表示させる 全く新しい方法です しかもそこにあることを 知らない場合であってもです ウィジェットが既に スタックに追加されている場合 スマートローテーションのおかげで ウィジェットは ユーザーの1日を便利 にする存在になるでしょう システムと オンデバイスインテリジェンスを 活用することで これら機能はウィジェットを より発見しやすく 自発的なものにし インテリジェントなホーム画面 体験に貢献します 皆さんのインテリジェントな ウィジェットを活用するのを 楽しみにしております ありがとうございました WWDCをお楽しみください
♪
-
-
9:14 - Donate INRelevantShortcuts for Widget Suggestions
// Donate INRelevantShortcut for Widget Suggestions in app // User has just made a purchase var relevantShortcuts: [INRelevantShortcut] = [] let intent = ViewRecentPurchasesIntent() intent.card = Card(identifier: card.identifier) intent.category = .all if let shortcut = INShortcut(intent: intent) { let relevantShortcut = INRelevantShortcut(shortcut: shortcut) relevantShortcut.shortcutRole = .information relevantShortcut.widgetKind = “CardRecentPurchasesWidget” let dateProvider = INDateRelevanceProvider(start: Date(), end: Date(timeIntervalSinceNow: 1800)) relevantShortcut.relevanceProviders = [dateProvider] relevantShortcuts.append(relevantShortcut) } INRelevantShortcutStore.default.setRelevantShortcuts(relevantShortcuts) { (error) in if let error = error { print("Failed to set relevant shortcuts. \(error))") } else { print("Relevant shortcuts set.") } }
-
12:35 - Adopting TimelineEntryRelevance for Smart Rotate
// Appending TimelineEntryRelevance to a TimelineEntry in widget extension for Smart Rotate struct CardRecentPurchasesEntry: TimelineEntry { let date: Date let relevance: TimelineEntryRelevance? let card: IntentCard? let category: PurchaseCategory } let relevance = TimelineEntryRelevance(score: 16.29, duration: 1800) let entry = CardRecentPurchasesEntry(date: Date(), relevance: relevance, card: card, category: category)
-
17:01 - Donate INIntents through INInteraction for Widget Suggestions and Smart Rotations
// Donate INIntent in a card's purchases list in the app .onAppear { let intent = ViewRecentPurchasesIntent() intent.card = Card(identifier: card.id.uuidString, displayString: card.name) intent.category = .all let interaction = INInteraction(intent: intent, response: nil) interaction.donate { error in if let error = error { print(error.localizedDescription) } } }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。