見出し画像

【所要時間30秒】とりあえずWidgetKitでウィジェットをつくってみる手順 #WWDC20 #iOS14

WWDC 2020のセッション"Meet WidgetKit"やではウィジェットの意義や設計コンセプトについても語られており、実装解説としては"Widgets Code-along"というセッションがパート1〜3まであります。実際のプロダクトに投入するのであれば必見の内容ですが、本記事では概念的なところはばっさりカットして「とりあえずの作り方」を紹介したいと思います。

Xcodeの扱いに慣れていれば30秒でできます。もちろんこれでプロダクトとしてリリースするわけにはいきませんが、忙しくてキャッチアップする時間がないという方には、iOS 14のまったく新しい機能であるウィジェットを簡単であれ30秒だけ手を動かしてつくってみるというはやっておいて損はないかと思います。


とりあえずつくってみる手順

プロジェクト作成

プロジェクトを作成します(僕が試したのはiOSのAppテンプレートだが、macOSでも、既存プロジェクトでも何でもOK)。

Widget ExtensionはSwift UI専用ですが、本体のInterfaceは"Storyboard"/"SwiftUI"どちらでもOKです。

Widget Extensionのターゲット作成

新規ターゲット作成ウィンドウで、"Widget Extension"を選択します。

画像1

Build & Run

もう準備OKです。ビルドしてiOS 14が入ったデバイスにインストールしてみましょう。

ホーム画面で既にウィジェットとして表示されています。

画像2

ウィジェット検索画面にもちゃんとリストアップされています。

画像3

以上。

生成されたコードを見てみる

要はテンプレートから生成されたまんまをビルドしただけ、という話なので、せめてどういうコードが生成されて、スクリーンショットに示したようなウィジェットになったのか、その中身を見てみましょう。

Widget Extensionのテンプレートから生成されたSwiftファイルを見てみると、Widgetプロトコルに準拠するこちらがの構造体がウィジェットのExtensionのエントリポイントとなっています。

@main
struct MyFirstWidgetExtentsion: Widget {
   private let kind: String = "MyFirstWidgetExtentsion"

   public var body: some WidgetConfiguration {
       IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider(), placeholder: PlaceholderView()) { entry in
           MyFirstWidgetExtentsionEntryView(entry: entry)
       }
       .configurationDisplayName("My Widget")
       .description("This is an example widget.")
   }
}

MyFirstWidgetExtentsionEntryViewは次のようなTextをひとつもつ構造体です。

struct MyFirstWidgetExtentsionEntryView : View {
   var entry: Provider.Entry

   var body: some View {
       Text(entry.date, style: .time)
   }
}

で、ここに出てくるProviderは次のようにIntentTimelineProviderプロトコルにする構造体で、現在時刻を取得する実装になっています。

struct Provider: IntentTimelineProvider {
   public func snapshot(for configuration: ConfigurationIntent, with context: Context, completion: @escaping (SimpleEntry) -> ()) {
       let entry = SimpleEntry(date: Date(), configuration: configuration)
       completion(entry)
   }

   public func timeline(for configuration: ConfigurationIntent, with context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
       var entries: [SimpleEntry] = []

       // Generate a timeline consisting of five entries an hour apart, starting from the current date.
       let currentDate = Date()
       for hourOffset in 0 ..< 5 {
           let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
           let entry = SimpleEntry(date: entryDate, configuration: configuration)
           entries.append(entry)
       }

       let timeline = Timeline(entries: entries, policy: .atEnd)
       completion(timeline)
   }
}

というわけでこのウィジェットはスクショにあった通り時刻をテキスト表示する機能を持っている、ということがわかります。

またWidget Extensionターゲット作成時に生成されるファイル群の中に、Assets.xcassetsがあります。ここにAppIconやAccentColor, WidgetBackgroundが設定できます。

画像4


ここから先は

0字
昨年は書籍という形にまとめましたが、今年はこのマガジンに集約することにしました。 最初は記事が少ないので格安から開始して、充実してくるごとに本来あるべき価格に戻していく予定です。というわけで早いうちに買うと非常にお得です。 昨年の書籍は約80ページ+本に載せなかった事項もたくさん、ということで最終的にはそれなりの量になるのではと思います。

堤がWWDC 2020およびiOS 14についてセッションやサンプルを見つつ勉強したことを記事にしていくマガジンです。NDAの都合上、Ap…

最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/