WidgetKit概要

## 前置き
2020からWidgetKitが登場し、iOSだとホームからWidgetを見たり編集することができました。WWDCの発表について簡単にまとめたものをこちら備忘録としてまとめたいとおもいます。

## 見出し
1. 概要
2. WWDC20
3. WWDC21
4. WWDC22

### 1, 概要
2020から登場したwidgetですが、ホーム画面にも表示できるwidgetについてはAndroidが先に導入済みであり、widgetのサイズを自由に変えたりWidgetから直接アプリの機能を使ったり比較的自由度の高いという印象です。個人的にはよく聞く話ですがiOSでは比較的制限を多くして統一的で綺麗なデザインと使いやすいUIを目指しているので、あまりカスタマイズ性はすくないのかなと思っています。ただ、近年のupdateにあるとおり、統一性をもたせつつもより開発者の個性を出しながらユーザーにもアプリ体験の向上を図るためにカスタマイズ性をどんどん増やしているのかなと思っています。

https://www.android.com/intl/ja_jp/articles/45/
https://www.macworld.com/article/232332/how-to-use-the-iphones-today-view-and-manage-its-widgets.html

### 2, WWDC20
Widgetについて初めて導入された年になり、以下のように様々な機能や実装の紹介をしていました。
- widgetの作成方法および概念
- SiriSugestionに表示する方法
- SmartStackによるユーザーの行動に基づいたWidgetの表示

ここでは主にWidgetの作成方法および概念に焦点をあてていきたいと思います。
WidgetはiphoneのホームやTodayView、MacのNotificationCenterで簡単にユーザーが情報を確認できるため優れたユーザー体験を提供します。Glanceable,Relevant,Personalizedの３つの主要素を満たすと特に優れたWidgetであると述べられています。
- Glanceable  
ユーザーは基本的に数秒しかホームを見ないので、そこで簡単にかつ特に操作することなくアプリのメインのコンテンツを表示することが重要。

- Relevant  
ユーザーの１日を考えると、例えば朝天気を確認して、昼にはTODOリストを確認、夜にはMusicをかけるみたいなケースが考えられる。そうした時に、必要なタイミングで必要なWidgetがでていたらユーザーとしてはとても優れた体験になるがそれを可能にするのがSmartStackである。SmartStackは複数のWidgetを１つのViewの中に格納しスワイプで切り替えることができる（PageViewのようなイメージ）。SmartStackはデバイスのシステムがもつintelligenceによってトップに表示するものを自動的に選択する。開発者としてはSiri Shortcuts donationsやwidgetKitAPIを使って優先順位を変えることも可能である。

- Personalication  
Widgetは３種類の大きさがあり、すべての大きさをアプリはサポートする必要はないかもしれないができれば複数のサイズをサポートする方がユーザーにとっても選択肢がふえて嬉しいので、推奨される。また、Widgetの編集をすることで例えば天気アプリでは現在地を変更でき、簡単にユーザーが好きな場所の天気をWidgetで確認することができる。

Widgetの設計思想としては、まずユーザーはHomeスクリーンを1日で90回以上みてかつ数秒しかみていないので、Homeスクリーンに表示されるWidgetがローディング中であることは避けたい。ということで、WidgetKitとしてはタイムラインの一連のView階層を返すものにし、タイムラインにViewをパッケージ化してホームに送ることで、ホームは設定された時間にそってパッケージのViewをロードして表示するだけですみ、立ち上げプロセスを省略することでより即時に表示することができるという処理のフローにしている。つまり、Viewはあらかじめ用意されているということであり、これはWidgetをホームに追加するときにみるWidgetのプレビューでも同じことがいえる。　　
Widgetは前述のとおりあらかじめ用意しているものであり、かつアプリとは基本的に独立したものあるので、何かしらのタイミングで更新する必要もでてくる（例えばTODOアプリで情報を更新した時とか）。ということでWidgetのリロードが必要がでてくるが下記のタイミングでそれが可能となる。
1. アプリからWidgetのリロードAPI
2. あらかじめリロードのスケジュールを設定

また、widgetを構成する要素として以下のものがある。
1. kind
WidgetのID的存在。WidgetExtensionは複数のWidgetを含むことができるので、kindで区別する

2. configuration
widgetの主要な要素でViewやタイムラインの設定を含む。種類としてはStaticConfigurationとIntentConfigurationが存在する。
StaticConfigurationとは、編集できない静的なもの（musicとか）でIntentConfigurationは逆に編集が可能なもの（天気アプリ、Reminderなど）

3. supprtedFamilies
Widgetのサイズのこと。デフォルトでは全部サポートするようになっている。

4. placeholder
デフォルトのWidgetのコンテンツのこと。特定のデータとかは含まずあくまでPlaceHolderの役割。注意点としてはいつこのUIが取得されるかはわからないことで、代表的なタイミングとしてはデバイスの環境が変わった時など。

GlanceableWidgetを作るためにStateLessUIであるので、mini appとは違いかつスクロールもできない。またアニメーションもタップ操作もできない。（WWDC23でとの一番の相違点ですね）。WWDC20ではあくまでWidgetは静的なもので、ユーザーに簡単に情報にアクセスしつつwidgetタップによってアプリに遷移してDeepLinkによって目的の画面にすぐに遷移できることを目的としています。
また、Widget内に複数のDeeplinkを設置でき、musicアプリのWidgetのように複数のアルバムを表示してそれぞれのタップによって特定のアルバムに簡単に遷移することが可能です。
Widgetを構成するViewの詳細については以下の通りです。
- placeholder UI
前述のとおり

- Snapshot
システムが素早く表示する必要があるときに返されるもの。特にWidgetの追加するときに表示するときに使われる。基本的にタイムラインの最初のエントリーとSnapshotは同一

- Timeline
Viewと表示データと日付が組み合わさったもの。タイムラインはダークモードとライトモードの両方に対応する必要がある。WidgetKitextensionがこれらのエントリーをシステムに返す時View階層をディスクにシリアライズすることで結果として個々のエントリーをその時刻に即時でレンダリングする。これによって、システムは多数のWidgetを多数のタイムラインで動かすことができる。基本てkにタイムラインは数日分のコンテンツを返す必要があり、また最新の情報を返す必要があるときもある。この最新の情報を返すのをリロードとよぶ（前述のとおり）。リロードが行われるとシステムはWidgetKitextensionに新しいタイムラインをもとめる。これで返す情報を最新のものにすれば表示されるWidgetは最新のタイムラインに基づいた最新の情報を表示することができる。TimeLineはTimelineProviderによって返すようになっている。
リロードのタイミングはTimelineProvider内の関数で設定でき、特定の日付やTimelineの完了時などを選べる。またシステム環境が変わったときは強制的にリロードがおこる。また、アプリからシステムにリロードを依頼することもできる。例えばバックグラウンド通知、アプリでのデータ操作などが起こった時にアプリからWidgetkitAPIをつかって依頼することができる。ただしこのリロード（アプリがフォアグラウンドのときのリロード）は特にアプリに関連する変更がありWidgetにそれが反映される時のみ行うことが推奨される。基本的にシステムが最終的にリロードのタイミングを決めるので必ずしも設定したタイミングでリロードがおこるとは限らない。
リロードについては、特定のkindをえらんだり、全選択したりと選ぶことができる。
また、Widgetに表示する情報をサーバーから取得するケースでは、Background URLSessionを使うことで対応できるがネットワークの使用量に注意して必要な分だけの通信に抑える必要がある。

Meet WidgetKit:https://developer.apple.com/videos/play/wwdc2020/10028/

### 3, WWDC21
2021年は主にInterigenceに関する話題が多く、Widgetをどう効率的にユーザーに見せるかについて焦点があてられていると感じました。主要な点は以下の通りです。

- iPad  
いままでWidgetはiOSやMacでのNotificationCenterで見ることができたが、iPadOS15からiPadのホーム画面でもWidgetを利用することが可能になった。

- Widget Intelligence  
iPhoneyやiPadではWidgetアプリを長押ししてアプリ同士を同じ場所に置くと自動的にSmartStackとなる。iOS14まではSmartRotateと呼ばれるシステムによる自動的なスクロール機能が搭載されていたが、iOS15からはWidgetSuggestionsという機能が新たに搭載される。WidgetSuggestionsはSmartStackにユーザーの行動などを学習して、ユーザーにとって価値のある新しいWidgetを自動的に挿入し、自動的に追加されたものは再度システムが適切なタイミングでSmartStackから削除を行う。システムに開発したアプリのWidgetをSuggestしてもらうにはDonationする必要があるが、Donationには、ユーザーにとって価値のあり一目でわかる情報を提供することを念頭に置く。
Donationは以下の３種類
1. InRelevantShortcut(WidgetSuggestionにDonate)  
アプリがユーザーにウィジェットを表示する関連性の高い状況を認識した時にホーム画面にウィジェットがないときにシステムがスマートスタックに積極的に挿入するようになる（上記のWidgetSuggegtion）。これは関連する期間を指定するか、shortcurRoleを設定することでユーザーの行動パターンに基づいて挿入タイミングを自動的にシステムが決定する。static, intent 両方のconfigurationに対応している。

2. TimelineEntryRelevance(SmartRotateにDonate)  
WidgetKitで作成したタイムラインエントリについてTimelineEntryRelevanceを設定することで関連性を指定できる。この関連性によって、Widgetがスマートローテーションでスマートスタックに表示されるのにどのくらい価値があるのかがきまる。設定は数値で行い、他のエントリとの相対比較で関連性は最終的にきまる。また、その数値が有効な期間も設定することもでき、その期間が過ぎるとシステムはそのスコアをゼロと扱う。

3. INInteraction(WidgetSuggestion、SmartRotateの両方にDonate)  
アプリがWidgetに示す情報に対応するアプリ内の情報をユーザーが見るたびにINInteractionをシステムに送り、それを元にシステムが学習していき、それを元にWidgetSuggestion、SmartRotateを自動的に提供する

Add intelligence to your widgets：https://developer.apple.com/videos/play/wwdc2021/10049/


### 4, WWDC22 
WWDC22にでは主に外観に関する変更点が多いと感じました。主要な点は以下の通りです。

- watchOSでのwidget対応  
以前まではClockKitを用いてWatchOSのComplicationを実装していたがWidgetKitに統一された。　

- VibrantRendrindMode  
ロック画面での色のモード露なり明るい色は不透明に、暗い色は背景のぼかしが目立たなくなるので、透明色は非推奨となり代わりに濃い色が推奨される

- AccesoryWidgetBackgroundView  
一部のスタイルで用いられる背景用のViewでそれぞれの画面スタイルに適した外観になるように自動的に調整される。

Dive into App Intents：https://developer.apple.com/videos/play/wwdc2022/10032
Complications and widgets: Reloaded：https://developer.apple.com/videos/play/wwdc2022/10050