😽

WidgetExtensionで設定を作る

2020/10/11に公開

この記事について

iOS14で出たWidgetKitを使ってWidgetの作成したときの調査内容や作成手順を書いてきます。
今回はIntetをつかったWidgetの設定項目の作成についてを書いていきます。

調査する際はこちらの内容をもとに調査をしていました。
https://developer.apple.com/documentation/widgetkit/making-a-configurable-widget

環境

Xcode 12.0で試しています。

手順

Widget ExtensionのTarget作成

まだTargetを作成していない方は「File > New > Target」からWidgetExtensionを選択して、ターゲットを追加します。

このときInclude Configuration Intentにチェックを入れておくと、設定項目を作るためのファイルやコードを自動生成してくれるので便利です。
また、.intentdefintionファイルがすでにあるプロジェクトは、すでにあるものをWidget Extensionのビルドターゲットに設定して使い回すこともできます。

Intetの名前変更

生成したIntentファイルのCustom Intentsの名前を好きに変えることができます。
必要に応じて適宜変えてください。

この名前は後ほどXcodeが自動生成するクラスの名前になるので注意してください。

名前変更後はIntentのクラス名も変更されるのでSwiftのコードの方も変えてください。
生成されたクラスの名前は<変更したCustomIntentの名前>Intentで、サフィックスにInentがつきます。

Widget用の設定の変更

Target作成時に自動生成した場合Include Configuration Intentにチェックを入れた場合はこの設定は自動でされるようです。

自動生成していない場合は、CategoryViewWidgetsIntent is eligible for widgetsにチェックをいれてください。

静的な設定を追加する

Switchで表示のOnとOffが切り替わる静的な設定を作っていきます。

Intentの設定項目の追加

先の手順で作成したCustom IntentParametersの項目に、適当なパラメータを追加します。

TypeBooleanにしておくことで、設定画面の内容にトグルの設定項目が自動生成されます。

Configurableの項目のUser can edit value in Shortcuts, widgets and Add to Siriにチェックを入れないとWidgetの設定画面に設定項目として出ないので注意してください。

ビルドして設定確認

Widgetの長押しをしてEdit Widgetから設定画面を開ます。

開いた画面に先程の設定項目のトグルが表示されていたら完成です。
他にもユーザーがキーボードから入力できるStringや、日付選択できるDate Componentsなどがあるので適切なTypeを選んでください。

設定項目の保存などは自動で保持されるようです。

データから動的に設定項目を追加する

アプリ本体のデータなどを使って設定項目を作ることもできます。

Intetnts ExtensionのTargetを作成

「File > New > Target」からIntents ExtensionのTargetを追加します。
すでにIntents ExtensionのTargetがプロジェクトにある場合は作成せず、使い回すことができます。

.intentdefinitionのビルドターゲット設定

まだ追加されていなければ.intentdefinitionをIntents Extensionのビルドターゲットに追加します。

Typeの追加

.intentdefinitionの左下にある「+」ボタンで、New Typeを選択してカスタムクラスを追加し、適宜必要なpropertyを追加します。

Custom IntentにParameterを追加

追加したTypeをCustom Intentのパラメータに設定します。
このときDynamic OptionsOption are Provided dynamicallyのチェックをつけてください。
これにより、後ほど使うコードが自動生成されるようになります。

今回は候補から複数選択ができるように、追加したParametersにSupport multiple valueのチェックを入れておきます。

IntentHandlerの実装

INExtensionを継承したIntents Extensionのエントリポイントに<Custom Intentの名前>IntentHandlingを追加で継承するように実装してください。
この〇〇IntentHandlingは自動生成されます。

また、Intents Extensionのエントリポイントは生成時はデフォルトでIntentHandlerのクラス名で自動生成されていると思います。

IntentHandlerを継承すると、Custom IntentのDynamic Optionsの項目にチェックを入れているとfunc provide<Typeに追加したクラス名>OptionCollection(...のようなメソッドを追加するように促されます。

対してSupport multiple valueにチェックを入れていないとCollectionのサフィックスがつかない別のメソッドになるようなので注意してください。

あとは設定項目に出したいデータをこのメソッドで返してあげれば完成です。

Widgetの設定が出たら選択肢の追加に成功です。
こちらのスクショは実際にEdit Widgetに選択肢が出るようになった画面です。

リストから選択された値を使う

Widget Extension側の実装をしていきます。
カスタムインテントに設定されたデータ型からEdit Widgetの画面で設定された値は、IntentTimelineProviderを継承したクラスから取得します。

もし、Support multiple valueを選択した場合はチェックリストでいくつかのデータを選択する形になっていると思います。
Widget Extension側では選択された値のみの配列が取得できるようになっており、独自でフィルターする必要はなさそうでした。

まとめ

Widgetの設定を作りたい場合はおおまかなに以下の3つの作業が必要です。

  • IntentdefinitionにCustom Intentを追加する
  • WidgetでXcodeが自動生成したクラスを使って表示制御をする
  • 動的に設定を作りたい場合はIntents Extensionで制御する

Custom Intentはたくさん設定項目があるので注意してください。
Option are Provided dynamicallyの設定を忘れてすごく時間を浪費しました。

Discussion