【Swift】Widgetの作り方 〜iOS 16対応版〜

Advent Calendar 2022

この記事はレコチョク Advent Calendar 2022の19日目の記事となります。

はじめに

最近チェンソーマンのエンディングテーマばかり聞いている神山です。
株式会社レコチョクでiOSアプリ開発をしています。

先月になりますが、ホーム画面に配置できるウィジェットをタワーレコード株式会社と弊社が共同で開発してるTOWER RECORDS MUSICという音楽サブスクリプションサービスのiOSアプリに導入しました。

https://music.tower.jp/

ということで今回は、ウィジェットの概要、実装方法についてご紹介しようと思います。

ウィジェットとは

ウィジェットとはアプリを起動せずとも、ユーザーの関心のあるコンテンツや一目で分かる情報を表示し、素早くアクセスして詳細を確認できるようにしたものです。

ウィジェットはさまざまなサイズで作成でき、ユーザーは自分にとって重要な情報をホーム画面、iOS16からはロック画面にも表示できるようになりました。

ホーム画面 ロック画面
widget_home.jpg widget_lock.jpg

開発環境

  • Xcode: 14.0.1
  • iOS: 16.0

実装方法

実際にアプリを作成してウィジェットの実装方法を確認してみます。

Widget Extensionの追加

まずはじめにターゲットにウィジェットを作成するためのテンプレートとして「Widget Extension」を作成します。
以下の順番で作成できます。

  1. 「File」→「New」→「Target」を選択
  2. 「Widget Extension」を選択し「Next」を選択
  3. 「Widget Extension」の名前を入力(ここではQiitaWidgetExtensionにします)
  4. 「Include Configuration Intent」のチェックボックスを必要に応じてチェックを入れる
  5. 「Finish」を選択し作成完了

widget_create.png

※ 「Include Configuration Intent」にチェックを入れると、ユーザーが自らウィジェットをカスタマイズできるようになる設定ファイルを作成と同時に追加できます。

カスタマイズできるウィジェットを長押しすると、「ウィジェットを編集する」という項目を選択できるようになります。

例えば、現在時刻を表示する地域を指定する時計ウィジェットや都市の郵便番号が必要な天気ウィジェット、追跡番号が必要な荷物追跡ウィジェットが挙げられます。

widget_configuration.jpg

ウィジェットの構成要素

Widget Extensionを追加するだけで、現在時刻を表示するウィジェットを追加できるファイルが自動生成されます。(QiitaWidgetExtension.swift)

widget_template.jpg

このテンプレートにウィジェットを生成するための構成要素が全て記載されていますので順に確認してみましょう。

以下、自動生成されたソースコードになります。

@main

ウィジェットが起動した際に最初に実行されるエントリーポイントです。

ここで表示するウィジェットの各設定を行います。

  • 各役割説明
    • kind・・・ウィジェットの識別子。複数のウィジェットを作成した際に、どのウィジェットかを判別するために使用します。
    • IntentConfiguration・・・ユーザーがカスタマイズできるウィジェットを作成します。
    • configurationDisplayName・・・ウィジェット作成画面のタイトル名を表示します。
    • description・・・ウィジェット作成画面の説明文を表示します。
    • supportedFamilies・・・作成可能なウィジェットのサイズを指定します。指定しなければデフォルトとなり、小・中・大全てのサイズを作成できます。

widget_description.jpg

※ ユーザーがカスタマイズできるウィジェットがIntentConfigurationに対して、カスタマイズができず表示のみを行うウィジェットの場合はStaticConfigurationを使用します。

TimelineEntry

ウィジェットにデータを表示するタイミングを教えるための日付(Date)を提供するプロトコルです。

TimelineEntryを準拠させることでウィジェット用のデータ構造体を作成できます。

TimelineProvider(IntentTimelineProvider)

ウィジェットの更新タイミングを提供するプロトコルです。

ここで設定した更新要求に基づいてウィジェットが更新されます。

  • placeholder
    • getTimelineのcompletionが呼ばれるまで、代わりに表示するデータを設定します。
    • この設定されたデータに基づいてスケルトンビューのようなものを表示できます。

widget_skelton.jpg

  • getSnapshot
    • ウィジェット作成画面で表示する際のデータを設定します。

widget_snapshot.jpg

  • getTimeline
    • ウィジェットを作成、更新後に表示するデータを設定します。

widget_timeline.jpg

ユーザーがカスタマイズできるウィジェット

IntentConfigurationを設定すればウィジェットをカスタマイズできますが、デフォルトでは何も指定してないためカスタマイズできません。

今回は一例として、編集した際に候補として表示した文言をウィジェットに表示できるようにしてみます。

QiitaWidgetExtension.intentdefinitionファイルに対して新たに設定を追加する必要があり、以下が実行手順になります。

※ Configurationの命名をQiitaConfigurationに変更しています

  1. Enumの追加(QiitaのEnumを作成しました)、各Caseに値を設定(qiita1, qiita2, qiita3のcaseを作成しました)

widget_enum.png

  1. ConfigurationのParameterに値を追加(qiitaParameterを作成しました)
  2. qiitaParameterのTypeに先ほど作成したEnumのQiitaを適用
  3. Configurable[User can edit value in Shortcuts, widgets, and Add to Siri]にチェックを入れ、デフォルト値を設定

widget_parameter.png

これらの設定が完了すると、「ウィジェットを編集」の選択ができるようになり、カスタマイズ可能なウィジェットを作成できます。

widget_edit.jpg

ロック画面のウィジェット

iOS 16からはロック画面にもウィジェットを配置できます。

ロック画面には3種類のウィジェットを追加でき、ロック画面用のWidgetFamily(.accessoryInline, .accessoryRectangular, .accessoryCircular)をsupportedFamiliesに追加するだけになります。

widget_ios16.jpg

まとめ

ウィジェットはユーザーがアプリを起動せずともコンテンツを表示でき、アプリのUX向上につながる便利な機能の1つです。

ウィジェットの概要・実装方法について間単にまとめてみました。導入の一助となれば幸いです。

最後まで読んでいただきありがとうございました。

明日のレコチョク Advent Calendarは20日目「DAOって何?初心者におすすめのDAOを紹介」です。お楽しみに!

参考文献

Creating a Widget Extension

Creating Lock Screen Widgets and Watch Complications