iOS14 Widget Configuration まとめ2
今回は、前回の Widget Configuration まとめ Part1 に続き、後半の内容をまとめていきたいと思います。
目次
Widget Configuration UI のタイトルや内容背景の色などをカスタマイズする方法について
Text
SwiftUI 変更のうち "configurationDisplayName" および "description" を、Widget Extension 内でタイトルと内容が変更できます。
Color
アプリケーションのカラースキームに合わすため Widget Configuration UI の BackgroundColor と AccentColor を変更することができます。
そのためには Widget Extension のアセットカタログに、それぞれの名前の色を追加する必要があります(AccentColor, BackgroundColor)。次に色の名前を Widget Extension の Build Settings に追加する必要があります。
Parameter visibility
他のパラメータ値に基づいて、特定のパラメーターを隠したり、表示したりすることもできます。これは Xcode の Intent Definition File で表示をコントロールしたいパラメータを親として設定することで実現することができます。
下記は、mirrorCalendarApp
パラメータを calendar
の親パラメータとして設定した場合の例です。
Widget System Intelligence について
iOS14 ではホーム画面に Widget を追加するだけでなく、複数の Widget を Stack にまとめて、様々な Widget を一ヶ所で簡単にスワイプして切り替えていくことができます。 これらの Stack では、システムが自動的に Stack の先頭に来る Widget をローテーションして、有用でタイムリーな情報を提供できることです。
スタックはタイムリーに理解できる明確な数値をユーザに提供するべきです。アプリケーションのユーザにとって関連性が高いタイムリーな情報がある時に、Widget は前面に表示されるべきです。雷がきそうなときには、Widget を前面で必要としますが、通常の天気の場合はあまり関連性は高くありません。
システムが特定の Widget を前面表示する理由は下記の2つがあります。
- ユーザの行動に基づいて表示される
- ユーザが特定の時間に典型的に見に行く情報を、提供する Widget は前面表示されやすくなります。
- アプリケーションからの適切な情報に基づいて表示される
ユーザの行動に基づいて表示する
ユーザが情報を得るためにアプリケーションをよく見る状況では、システムが Widget を前面に表示しようとします。
iOS12 で Shortcuts と Custom Intent Donation の概念が導入されました。これらは、ユーザがアプリケーション内で何をしているのかをシステムが理解する方法を提供するものです。システムはこの情報をもとにユーザが求めている行動予測を Spotlight で提供します。
iOS14 の新機能として、同じ Donation が Widget をいつ前面表示するとタイムリーなのかシステムに対して通知します。システムインテリジェンスが Widget をローテーションできるように、同じ Intent でホストアプリケーションによる Donation ができるよう設定する必要があります。
Intent でドネートする設定
まず Intent について Siri からの提案を有効にするフラグを立てます。
すると、"Suggestions" というセクションが開きます。
ドネートがあった場合にシステムが行うこと
ユーザが正午になると、AcmeCard の食料品購入を見ていて、夕方になると SoupPay カードのレストラン購入を確認しているとします。ホストアプリケーションはこのように Intent をドネートします。この Donation に基づいて、システムはどのカードがいつ確認されているかを認識します。また、複数の条件が組み合わせてドネートする場合は Supported Combinations がシステムと通信する手段であり、設定したパラメーターはユーザが求めている情報である必要があります。
設定のまとめ
- Widget についての Intent を設定する
- システムが予測できるように Siri からの提案が有効になるように設定する
- Supported Combinations を設定する
- システムに予測して欲しいパラメータだけを含めるように気を付ける
- ユーザがアプリケーション内で、その情報を見た時に Intent をドネートできるように設定する
アプリケーションからの適切な情報に基づいて表示する
Widget が関連性が高い情報を持っているということをシステムに伝えるには、TimelineEntry で TimelineEntryRelevance オブジェクトを送信します。
TimelineEntry は実質的に3つの要素で成り立っています。
- Entry を表示すべき時間を決定する日付とタイムスタンプ
- 表示する View
- Entry の関連性の高さ
関連性の高さは TimelineEntryRelevance オブジェクトで表され、スコアと有効期限のフィールドがあります。
import WidgetKit public struct TimelineEntryRelevance: Codable, Hashable { public let score: Float public let duration: TimeInterval }
- score
- スコアとは過去に提供された全ての Entry と比べて、その Entry がどれだけ関連性が高いかを示す値です。システムは他の Entry との相対関係でしかスコアを考慮しないため、範囲とスケールについては、アプリケーションごとに定義しても大丈夫とのことです。例外として、スコアがゼロかマイナスの場合システムに対して Widget が今のところ関連性の高い情報を持っていないことを示します。
下記の例では、$50 を超えた購入があった時に、最も関連性の高い Widget であることをシステムに通知している例です。また、これらの他の Widget が提供スコアとは関係性がなく、スコアは自分の Widget から提供したスコアの中だけで比較されます。
- duration
- 有効期限は関連性の高さのスコアが固定できる期間をうまくコントロールできるような場合に使用します。それ以外の場合は、有効期限はゼロのままで問題はないようです。これにより、現在のスコアは次の TimelineEntryRelevance を受け取るまで、有効になります。
下記はバスケットボールの試合の進行を表す Widget の例です。試合の開始時に score1を持つ Entry を作って duration は試合の長さに固定します。これにより、それ以降の Timeline Entry 更新について TimelineEntryRlevance フィールドを nil にしておけば、関連性の高さに影響を与えずに更新を続けることができます。Entry を nil にすることでシステムに対して、関連性の高さについてはその更新を無視するように伝えることになります。