iOSエンジニアのつぶやき

毎朝8:30に iOS 関連の技術について1つぶやいています。まれに釣りについてつぶやく可能性があります。

iOS14 Widget Configuration まとめ2

今回は、前回の Widget Configuration まとめ Part1 に続き、後半の内容をまとめていきたいと思います。

developer.apple.com

目次

  • Widget Configuration UI のタイトルや内容背景の色などをカスタマイズする方法について
  • Widget System Intelligence について

Widget Configuration UI のタイトルや内容背景の色などをカスタマイズする方法について

Text

SwiftUI 変更のうち "configurationDisplayName" および "description" を、Widget Extension 内でタイトルと内容が変更できます。

スクリーンショット 2020-10-21 10 14 05

Color

アプリケーションのカラースキームに合わすため Widget Configuration UI の BackgroundColor と AccentColor を変更することができます。

スクリーンショット 2020-10-21 10 16 10

そのためには Widget Extension のアセットカタログに、それぞれの名前の色を追加する必要があります(AccentColor, BackgroundColor)。次に色の名前を Widget Extension の Build Settings に追加する必要があります。

Parameter visibility

他のパラメータ値に基づいて、特定のパラメーターを隠したり、表示したりすることもできます。これは Xcode の Intent Definition File で表示をコントロールしたいパラメータを親として設定することで実現することができます。

下記は、mirrorCalendarApp パラメータを calendar の親パラメータとして設定した場合の例です。

スクリーンショット 2020-10-21 10 24 59

Widget System Intelligence について

iOS14 ではホーム画面に Widget を追加するだけでなく、複数の Widget を Stack にまとめて、様々な Widget を一ヶ所で簡単にスワイプして切り替えていくことができます。 これらの Stack では、システムが自動的に Stack の先頭に来る Widget をローテーションして、有用でタイムリーな情報を提供できることです。

スタックはタイムリーに理解できる明確な数値をユーザに提供するべきです。アプリケーションのユーザにとって関連性が高いタイムリーな情報がある時に、Widget は前面に表示されるべきです。雷がきそうなときには、Widget を前面で必要としますが、通常の天気の場合はあまり関連性は高くありません。

システムが特定の Widget を前面表示する理由は下記の2つがあります。

  • ユーザの行動に基づいて表示される
    • ユーザが特定の時間に典型的に見に行く情報を、提供する Widget は前面表示されやすくなります。
  • アプリケーションからの適切な情報に基づいて表示される
    • 例えば、雷が到来している時などに Widget はシステムに対して関連性が高い更新があることを通知します。そうすることにより、システムは Widget を Stack の先頭に表示することを検討します。

ユーザの行動に基づいて表示する

ユーザが情報を得るためにアプリケーションをよく見る状況では、システムが Widget を前面に表示しようとします。

iOS12 で Shortcuts と Custom Intent Donation の概念が導入されました。これらは、ユーザがアプリケーション内で何をしているのかをシステムが理解する方法を提供するものです。システムはこの情報をもとにユーザが求めている行動予測を Spotlight で提供します。

iOS14 の新機能として、同じ Donation が Widget をいつ前面表示するとタイムリーなのかシステムに対して通知します。システムインテリジェンスが Widget をローテーションできるように、同じ Intent でホストアプリケーションによる Donation ができるよう設定する必要があります。

Intent でドネートする設定

まず Intent について Siri からの提案を有効にするフラグを立てます。

スクリーンショット 2020-10-21 11 22 55

すると、"Suggestions" というセクションが開きます。

スクリーンショット 2020-10-21 11 24 26

ドネートがあった場合にシステムが行うこと

ユーザが正午になると、AcmeCard の食料品購入を見ていて、夕方になると SoupPay カードのレストラン購入を確認しているとします。ホストアプリケーションはこのように Intent をドネートします。この Donation に基づいて、システムはどのカードがいつ確認されているかを認識します。また、複数の条件が組み合わせてドネートする場合は Supported Combinations がシステムと通信する手段であり、設定したパラメーターはユーザが求めている情報である必要があります。

設定のまとめ

  1. Widget についての Intent を設定する
  2. システムが予測できるように Siri からの提案が有効になるように設定する
  3. Supported Combinations を設定する
  4. システムに予測して欲しいパラメータだけを含めるように気を付ける
  5. ユーザがアプリケーション内で、その情報を見た時に Intent をドネートできるように設定する

アプリケーションからの適切な情報に基づいて表示する

Widget が関連性が高い情報を持っているということをシステムに伝えるには、TimelineEntry で TimelineEntryRelevance オブジェクトを送信します。

TimelineEntry は実質的に3つの要素で成り立っています。

  • Entry を表示すべき時間を決定する日付とタイムスタンプ
  • 表示する View
  • Entry の関連性の高さ

スクリーンショット 2020-10-21 11 47 01

関連性の高さは 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 から提供したスコアの中だけで比較されます。

スクリーンショット 2020-10-21 11 56 37

  • duration
    • 有効期限は関連性の高さのスコアが固定できる期間をうまくコントロールできるような場合に使用します。それ以外の場合は、有効期限はゼロのままで問題はないようです。これにより、現在のスコアは次の TimelineEntryRelevance を受け取るまで、有効になります。

下記はバスケットボールの試合の進行を表す Widget の例です。試合の開始時に score1を持つ Entry を作って duration は試合の長さに固定します。これにより、それ以降の Timeline Entry 更新について TimelineEntryRlevance フィールドを nil にしておけば、関連性の高さに影響を与えずに更新を続けることができます。Entry を nil にすることでシステムに対して、関連性の高さについてはその更新を無視するように伝えることになります。

スクリーンショット 2020-10-21 12 06 53

参考

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com