
【所要時間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"を選択します。

Build & Run
もう準備OKです。ビルドしてiOS 14が入ったデバイスにインストールしてみましょう。
ホーム画面で既にウィジェットとして表示されています。

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

以上。
生成されたコードを見てみる
要はテンプレートから生成されたまんまをビルドしただけ、という話なので、せめてどういうコードが生成されて、スクリーンショットに示したようなウィジェットになったのか、その中身を見てみましょう。
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が設定できます。

ここから先は

#WWDC2020 の勉強メモ
堤がWWDC 2020およびiOS 14についてセッションやサンプルを見つつ勉強したことを記事にしていくマガジンです。NDAの都合上、Ap…
最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/