iOS16から、Appleはロック画面のデザインを一新し、Widget extensionが使えるようになりました。
この記事では、iOS16ロック画面ウィジェットの実装方法についてご紹介します。

iOS16より前は、ウィジェットのサイズは3種類(systemSmall、 systemMedium、 systemLarget)でしたが、iOS16からはwidget familyに accessoryInline、accessoryCircular、 accessoryRectangularの3種類が追加されます。
この記事では、accessoryCircularのstatelessショートカットウィジェット とaccessoryRectangularの残高ウィジェットの二つを作成したいと思います。
要件
新しいウィジェットには、制限がいくつかあります。
- iOS16以上のみ対応
- SwiftUIのみ対応
- systemWidgetより小さいので、コンテンツにはよりわかりやすい情報が必要。
- 色はユーザー自身で設定。デフォルト色は白。
- 円形ウィジェットには円形のものしか表示できない。
実装を始める前に、Xcode14とiOS16のデバイスが必要です。
Widget Extensionの実装
- File → New → Target

- Widget Extensionを選択し、Target nameを入力。

- 「Activate widget scheme」をクリックする。

- 右側にウィジェットのプレビューが表示される。

ショートカットウィジェット
accessoryCircularをPreview とSupported Familyに追加してみましょう。

円形ウィジェットに「支払う」という文字が入ったPayPayアイコンを表示したい場合。

CircluarWidgetViewを作成し、中に画像とテキストを入れる。

circular widget familyには、CircluarWidgetViewを返す。


このウィジェット背景を透明の白にしたい場合は、上にZStackを追加し、ファーストレイヤーに背景色を追加する。


円形ウィジェットのUIが完成したら、タップの挙動を実装してから、このウィジェットをクリックしたときのDeeplinkを追加する。

ShortcutWidgetProvider
ウィジェットではプロバイダを使ってウィジェットのアップデートや情報の取得を行っていますが、ショートカットウィジェットでは、ステートや情報を設定する必要がありません。
簡単なプロバイダを作ってupdate timelineを.neverに設定します。

これでロック画面に作成したショートカットウィジェットが見えるようになりました!

残高ウィジェット
次に、残高ウィジェットと呼ばれるさらに複雑なウィジェットを作りたいと思います。
この残高ウィジェットでは、ユーザーのステートによって異なる表示をするので、リモートサーバーから情報を取得します。
このウィジェットはコンテンツを表示するのにより多くのスペースが必要になるので、widget familyのAccessaryRectangular を使用します。

角形ウィジェットには3つのステートがあります。
- 未ログイン
- ノーマル
- 残高有

残高ウィジェットと呼ばれる新しいウィジェットを作る。

RectangularWidgetViewというViewを作りましょう。
![]()
ステートによってViewの見た目は違うので、そのためのViewModelを作ってみましょう。

ViewModelと一緒にRectangularWidgetViewを返す。

RectangularWidgetViewでは、ViewModelのステートを使ってViewの出し分けをしています。
まず、未ログインのViewの実装から始めましょう。

未ログインのViewの実装

ノーマルのViewの実装

残高のViewの実装

クリックの挙動
ステートによって、ViewModelは異なるDeeplink URLを返します。

EntryViewでDeeplink URLを追加する。
![]()
StaticConfigurationとIntentConfiguration
残高ウィジェットプロバイダでは、ユーザーのログインや設定に基づいてウィジェットの情報を変更し、バックエンドサーバーからユーザーの残高を取得して、それに基づいて更新します。
先ほどのショートカットウィジェットでは、デフォルトのプロバイダであるTimelineProviderを使いましたが、今回は代わりにIntentTimelineProviderを使います。
ウィジェットプロバイダを使って、ユーザーは編集モードでウィジェットをクリックするとウィジェットをカスタマイズすることができます。
ウィジェット設定ページが表示されるので、そこでユーザーはウィジェットのオプションを選択できます。
ユーザーのプライバシーはこの世で一番大事なことなので、ロック画面に残高を表示するかどうかはユーザー自身で選んでもらいたいと思っています。
そのためには、ウィジェットのintentにshowBalanceというオプションを追加する必要があります。

では、ConfigurationIntentを作っていきましょう。
- ウィジェットの ConfigurationIntentを作成する。

- showBalanceというパラメーターを追加し、typeはBooleanを選択する。

TimelineProviderの代わりに、今回は IntentTimelineProviderを使う。

Widget Entryを使って、ウィジェットのViewをリロードする。

showBalanceの変数にはユーザーの設定値を使用する。
![]()
APIを呼び出し、残高を取得する。
![]()

ショートカットウィジェットと残高ウィジェットの二つができました。
場合によっては、システムウィジェットからの対応も必要になります。
その場合は、Widget bundleを使って複数のウィジェットに対応します。

ロック画面のウィジェットはiOS16以上のみの対応なので、OSの条件も必要になります。

これで二つのウィジェットの実装が完了しました。
iOS14以降、AppleはユーザーがPayPayアプリを新しく便利な形で使えるようなウィジェットを提供してきましたが、iOS16からはロック画面でも使えるようになります!
ウィジェットには色んな可能性があると思います。
ウィジェット実装の基本を学び、もっと面白いウィジェットを作る上でこの記事が皆さんのお役に立てばうれしいです。

PayPayでは皆、常に新しい技術を試してみるのが好きです。
iOS 14のウィジェットがリリースされたばかりの時も、ウィジェットを実装しました。
もちろん、iOS 16のウィジェットでも同様に、その姿勢を貫いていくつもりです。
PayPayでは、新しい技術やアイデアが好きな方々の入社をお待ちしています。



