Widgetはミニアプリではない
- Widget上で操作することは想定されておらず、スクロールやインタラクティブなUI (e.g. Switch) や動画などはサポートされない
- ただし、Widgetをタップするとディープリンクでアプリ内の適切な画面を開ける
- Smallサイズは1つのリンクしか持てない
- MediumとLargeサイズは複数のリンクを持つことができ、タップした領域によって別のディープリンクを開くことができる
画面は事前に描画される
- 「Widgetを表示するタイミングでアプリを起動してロードして...」という読み込み時間がないのでWidgetの変更がすぐに反映される
- ただし、初回表示時や設定変更時 (e.g. ダイナミックタイプの変更) には画面描画まで時間が掛かるのでPlaceholderが表示される
- SwiftUIの宣言的にViewを定義できる性質を活かした仕組み
- Timelineという仕組みによって画面更新のスケジューリングを行う
Widgetのバリエーション
- 1つのアプリは複数種類のWidgetを持てる
- 1つのアプリの中で複数の WidgetKit extension を持つこともできるが、1つの WidgetKit extension に複数Widgetをまとめることが推奨されている
-
WidgetBundle
を使うことで1つの WidgetKit extension に複数のWidgetをまとめることができる
-
- 1つのアプリの中で複数の WidgetKit extension を持つこともできるが、1つの WidgetKit extension に複数Widgetをまとめることが推奨されている
- 1つのWidgetは複数のサイズを持てる
-
WidgetFamily
に定義されている以下3種類がある- systemSmall
- systemMedium
- systemLarge
- どれか1つのサイズだけサポートしても良い
-
- 同じ種類・サイズのWidgetをホーム画面に複数個置ける
- Widgetの設定を変えることで別の見た目にすることが可能
Smart Stack
- 複数のWidgetを1つの枠にまとめられる機能
パーソナライズ (Widget Configuration)
- ホーム画面を編集モードにしてWidgetをタップするとWidgetの設定ができる
各キーワードについてもう少し詳しく
Timeline
- いつ、どのようなViewを表示するかをあらかじめ計画する
- Timelineの更新タイミング
- システムによる更新
-
ReloadPolicy
からシステムが更新に最適なタイミングを判断する - システムによってよく見られているWidgetだと判斷された場合はシステムがより頻繁に更新する
- つまり
ReloadPolicy
通りに更新されるわけではない?
- つまり
-
- アプリ起因による更新
-
WidgetCenter
を通じて任意のタイミングで- アプリ本体からでも WidgetKit extension からでも
-
URLSession
の background session が完了したタイミング- データをインターネットから取得してきた後など
- 負荷を上げないために頻繁に更新しすぎないよう注意
-
- システムによる更新
- 例外として、
Text
viewのパラメーターにDate型を渡して日時を表示する場合は、意図的に更新しなくても随時最新の日時に更新される- 詳しくは Keeping a Widget Up To Date の "Display Dynamic Dates" の項を参照のこと
Snapshot
- 現在の日時や状態などの情報が含まれる
TimelineEntry
を元にしてそれに対応する画面を返す - パラメーターで渡される
context.isPreview
がtrueのときは Widget Gallery で使用される- Widget Gallery とは、ホーム画面にWidgetを追加する際に見本のWidgetが表示される画面
Placeholder
- 初回表示時や設定変更時 (e.g. ダイナミックタイプの変更) に、まだTimelineが作成されていないときに表示される
- WidgetのViewに
.isPlaceholder(true)
を追加するだけで簡単に作成できる
SwiftUI gives you .isPlaceholder(true) in WidgetKit, which makes it incredibly simple to generate a placeholder Widget view ✨ pic.twitter.com/40Fw8TzfWE
— Jordan Singer (@jsngr) June 25, 2020
参考資料
- https://developer.apple.com/videos/play/wwdc2020/10028/
- https://developer.apple.com/videos/play/wwdc2020/10103/
- https://developer.apple.com/videos/play/wwdc2020/10034/
- https://developer.apple.com/videos/play/wwdc2020/10035/
- https://developer.apple.com/videos/play/wwdc2020/10036/
- https://developer.apple.com/documentation/widgetkit
- https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension
- https://developer.apple.com/documentation/widgetkit/making-a-configurable-widget
- https://developer.apple.com/documentation/widgetkit/keeping-a-widget-up-to-date