1. HOME
  2. ブログ
  3. IT技術
  4. iOS14に追加されたウィジェット実装してみた
iOS14に追加されたウィジェット実装してみた

iOS14に追加されたウィジェット実装してみた

はじめに

今回はウィジェットの表示、ウィジェットの編集、ディープリンクで特定の画面を開くところまでのデモアプリを作成しました。

本記事がウィジェットを実装される方のお役に少しでも立てば幸いです。

Widgetとは

WidgetとはUIのことで、ホーム画面を左にスワイプすると出てくるアイコン4つ分くらいの大きさのUIをWidgetと言います。

iOS14からWidgetがホーム画面にも追加できるようになりました。

WWDC20 - Videos - Apple Developer Meet WidgetKit から引用

Widgetの特徴

WWDC20 - Videos - Apple Developer Meet WidgetKit から引用

Widgetの特徴には以下の3つがあります。

  1. Glanceable(ひと目で分かる)
  2. Relevant(関連性がある)
  3. Personalized(個々にカスタマイズできる)

Glanceable(ひと目で分かる)

まず、ひと目で分かるという特徴についてです。

Widgetでは以下のように特定のコンテンツを表示することができ、ひと目で情報を確認することができます。

WWDC20 - Videos - Apple Developer Meet WidgetKit から引用

Relevant(関連性がある)

次に関連性があるという特徴についてです。

Widgetはユーザーが求めている情報を適切な時間で表示することができます。

例えば、朝起きた時に天気を確認し、音楽を聞くと言った場合、Widgetは起きる時間では天気の情報を表示し、10分後に音楽アプリの情報を表示するということができます。

また、Widgetには以下のようなスマートスタックというWidgetがあり、限られた画面スペースを最大限に活用し、システムが適切なタイミングでWidgetを回転させて表示します。(スワイプして表示を変えることもできます。)

WWDC20 - Videos - Apple Developer Meet WidgetKit から引用

Personalized(個々にカスタマイズできる)

最後に個々にカスタマイズできるという特徴についてです。

Widgetはユーザーに合わせて表示内容やサイズをカスタマイズすることができます。

例えば天気アプリでは、Widgetを長押ししてウィジェットの変更を選択することで、地域を選択することができます。

WWDC20 - Videos - Apple Developer Meet WidgetKit から引用

Widgetのサイズ

WidgetのサイズはWidgetFamilyというenumで定義されており、systemSmall、systemMedium、systemLargeという3種類のサイズがあります。

Widgetを導入する場合、全てのサイズに適応しなければならないわけではなく、どのWidgetサイズにアプリを適応させるかは開発者が決めることができます。

WWDC20 - Videos - Apple Developer Meet WidgetKit から引用

Widgetの更新

Widgetの更新にはTimelineを使用します。

開発者が更新したい時間にTimelineを設定することでWidgetを更新することができます。

また、Timelineを更新するには2つの方法があり、TimelineにReloadPolicyを設定する方法とWidgetCenterのメソッドを使って更新する方法の2つがあります。

WWDC20 - Videos - Apple Developer Meet WidgetKit から引用

ReloadPolicy

Timeline作成時にReloadPolicyを設定することで、Timelineの更新タイミングを設定することができます。

ReloadPolicyには「atEnd」「after(date: Date)」「never」の3種類があります。

  1. atEnd:設定したTimelineの最後でリロードを要求
  2. after(date: Date):特定の日付の後にリロードを要求
  3. never:Timelineをリロードしないよう指定

※注意点:ReloadPolicyを設定したからと言って、必ず指定した時間に更新されるわけではなく、最終的にSystem reloadsが適切なタイミングでリロードします。

WidgetCenter

WidgetCenterを使うことで、リロードをリクエストすることができます

  1. 特定のWidgetのリロードをリクエストする
    WidgetCenter.shared.reloadTimelines(ofKind:)
  2. 全てのWidgetのリロードをリクエストする
    WidgetCenter.shared.reloadAllTimelines()

WidgetCenterを使用することで、アプリ起動時やプッシュ通知受信時などのイベントからリロードをリクエストすることができます。

Widgetの編集

Widgetの編集は、IntentConfigurationを設定することで追加することができます。

IntentConfigurationを設定することで、Widgetに表示する内容をユーザーが選択できるようになります。

この機能を使って、株価アプリでは以下の画像のように表示する銘柄を選択できます。

WWDC20 - Videos - Apple Developer Meet WidgetKit から引用

Deep linking

Widgetにはディープリンクを追加することができ、ディープリンクを使って画面遷移した状態でアプリを表示することができます。

Widgetに追加できるディープリンクの数はWidgetのサイズによって違いがあり、systemSmallでは1つ、systemMedium、systemLargeでは複数のディープリンクが設定できます。

WWDC20 - Videos - Apple Developer Widgets Code-along,part 2: Alternate timelines から引用

Widgetの実装

今回デモアプリとして、ポケモンをテーブルに表示し、セルをタップした時にポケモンの画面に遷移するアプリを作成しました。

Widgetの編集で好きなポケモンを選択でき、またディープリンクでWidgetがタップされた時にポケモンの画面が表示されるようにしました。

Widgetの実装①

まずは作成したプロジェクトにWidgetを追加します。

メニューのFile → New → Target...からWidget Extensionを選択し、NextでWidgetExtensionを追加します。

追加されたファイルを開くと、日付が表示される簡単なWidgetが実装してあるので、あとはコードの追加と修正をすればWidgetを作成することができます。

まずは、追加されたファイル内のTimelineEntryを修正します。修正後のコードが以下になります。

dateとconfigurationはファイルを作成した時に実装されているもので、configurationには後で作成するMyPokemonIntentを指定しています。

また、WidgetのViewを作成する時に使用するクラスを追加します。今回はPokemonを追加しました。

Widgetの実装②

TimelineEntryが修正できたら、次にWidgetのViewを作成します。

entryには先ほど定義したTimelineEntryが入ってくるので、entryを使ってViewを作成します。

そして、一番下の「.widgetURL」でWidgetにディープリンクを追加します。

実際にViewを作成したコードが以下になります。

Widgetの実装③

Viewが作成できたので、次にIntentTimelineProviderを設定します。

pleceholder(in:)にはWidgetを追加する前のプレビュー表示に使うTimelineEntryを設定します。

getSnapshot(for:, in:, completion:)ではWidgetの情報を取得するまでの間、表示しておくTimelineEntryを設定します。

最後にgetTimeline(for:, in:, completion:)でTimelineの設定をします。
今回はWidgetの更新はを行わないため、一つだけEntryを作成し、policyを.neverに設定しました。

実際に設定したコードは以下になります。

Widgetの実装④

IntentTimelineProviderを実装することができたので、次にWidgetを設定します。

kindではWidgetを判別するための名前、configurationDisplayNameとdescriptionでは、Widgetを設定する時に表示する名前とWidgetについての説明文を設定します。

そして、最後のsupportedFamiliesでサポートするWidgetサイズを指定します。

実際に設定したコードは以下になります。

Widgetの実装⑤

最後にWidgetを編集するための機能を実装します。

XcodeのNewfileからIntentファイルを作成し、ParametersにEnumでMyPokemonを追加します。

そして、MyPokemonからTimelineEntryのPokemonを設定するように実装すれば、Widgetの実装完了です。

まとめ

今回実装したものは、Widgetの更新を行わず、またWidgetの編集機能も簡単なものでした。

実際のアプリに導入するとなると、ユーザーがアプリを操作した時や、プッシュ通知を受け取った時にWidgetの更新するような実装が必要になると思います。

またWidgetの編集も選択ができるだけでなくTextFieldを表示したり、Switchを表示したりすることもあるかもしれません。

実際に個人開発アプリに導入する機会などあれば、もうちょっと深掘りしながら導入していこうと思います。

本記事が何かお役に立てれば幸いです。

ご覧いただき、ありがとうございました。

書いた人はこんな人

いまむー(エンジニア)
いまむー(エンジニア)
未経験から2021年1月に株式会社ライトコード入社し、iOSエンジニアとして働かせていただいています。
まだまだ分からないことだらけで、日々分からないことと戦いながら仕事をしている初心者です。
ブログ記事は暖かい目で見ていただけるとありがたいです。

関連記事

採用情報

\ あの有名サービスに参画!? /

バックエンドエンジニア

\ クリエイティブの最前線 /

フロントエンドエンジニア

\ 世界を変える…! /

Androidエンジニア

\ みんなが使うアプリを創る /

iOSエンジニア