0Pricing
Swift Academy · レッスン

WidgetKitウィジェットの構築

タイムラインを使ってホーム画面ウィジェットを作成します。

「WidgetKitウィジェットの構築」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。

Widgetとは

Widgetは、ホーム画面、ロック画面、またはStandByに表示される、一目で確認できる小さなビューです。ミニアプリではないため、スクロールしたり任意のコードを実行したりすることはできません。WidgetKitを通じて指定したスケジュールに従い、システムが更新するデータのスナップショットを表示します。

import WidgetKit
import SwiftUI
// A widget = configuration + timeline of entries
// + a SwiftUI view that renders one entry

Widget Extensionのターゲット

Widgetはメインアプリではなく、独立したWidget Extensionターゲットとして提供します。独自のバンドルを持ち、独自のプロセスで実行されます。XcodeのWidget Extensionテンプレートから追加すると、設定とプロバイダーのひな形が作成されます。

import WidgetKit
// File > New > Target > Widget Extension
// The extension declares one or more widgets
// in a WidgetBundle if you have several.

Widgetの型

WidgetはWidgetプロトコルに準拠し、設定を返すbodyを公開します。この設定によって、kind識別子、タイムラインprovider、各エントリを描画するviewが結び付けられます。

import WidgetKit
import SwiftUI
struct WeatherWidget: Widget {
    var body: some WidgetConfiguration {
        StaticConfiguration(
            kind: "WeatherWidget",
            provider: WeatherProvider()) { entry in
            WeatherView(entry: entry)
        }
        .configurationDisplayName("Weather")
        .description("Shows the current forecast.")
    }
}

StaticとAppIntentの設定

StaticConfigurationは、ユーザーが選択する項目のないWidgetに使用します。AppIntentConfigurationを使うと、App Intentを通じてユーザーがWidgetをカスタマイズできます(都市やアカウントの選択など)。内容が固定されている場合はstatic、設定可能なWidgetにはintentベースの構成を選択してください。

import WidgetKit
// StaticConfiguration     -> no user choices
// AppIntentConfiguration  -> user-editable parameters
let kinds = "static vs configurable"
_ = kinds

タイムラインエントリ

Widgetが表示できる各時点はTimelineEntryです。これはdateと、ビューに必要な任意のデータを持つstructです。プロバイダーは、これらのエントリを順番に提供します。

import WidgetKit
struct WeatherEntry: TimelineEntry {
    let date: Date
    let temperature: Int
    let condition: String
}

Widgetのビュー

ビューは通常のSwiftUIですが、スクロール不可、インタラクションに制限あり、複数の固定サイズで適切に表示される必要があるという制約があります。エントリを読み取り、一目で確認できる簡潔な概要をレイアウトしてください。

import SwiftUI
import WidgetKit
struct WeatherView: View {
    let entry: WeatherEntry
    var body: some View {
        VStack {
            Text(entry.condition)
            Text("\(entry.temperature) degrees")
                .font(.title)
        }
    }
}

サポートするファミリー

supportedFamiliesでサポートするサイズを宣言します。.systemSmall、.systemMedium、.systemLarge、ロック画面の.accessoryRectangular/.accessoryCircularなどを指定できます。Widgetファミリーの環境を使って、ファミリーごとにレイアウトを調整してください。

import WidgetKit
import SwiftUI
// .configurationDisplayName(...)
// .supportedFamilies([.systemSmall, .systemMedium,
//                     .accessoryRectangular])
let families = "declare supported sizes"
_ = families

ファミリーへの適応

ビュー内で@Environment(\.widgetFamily)を読み取り、レイアウトを分岐します。これにより、コンパクトなsmall Widgetと、より情報量の多いmedium Widgetを、別々のWidgetを書かずに実現できます。

import SwiftUI
import WidgetKit
struct AdaptiveView: View {
    @Environment(\.widgetFamily) var family
    let entry: WeatherEntry
    var body: some View {
        if family == .systemSmall {
            Text("\(entry.temperature)")
        } else {
            Text("\(entry.condition) \(entry.temperature)")
        }
    }
}

コンテナの背景

最新のWidgetでは、containerBackground(for: .widget)を使って背景を宣言する必要があります。これにより、StandByやロック画面などの各コンテキストでシステムが正しく描画できます。宣言しないと、Widgetが拒否されたり、正しく表示されなかったりする可能性があります。

import SwiftUI
import WidgetKit
struct Bg: View {
    var body: some View {
        Text("Hi")
            .containerBackground(for: .widget) {
                Color.blue
            }
    }
}

アプリとのデータ共有

Widgetのプロセスは独立しているため、アプリのメモリ上の状態を読み取ることはできません。両方のターゲットからアクセスできる共有コンテナであるApp Groupを通じてデータを共有します。通常は、共有UserDefaultsスイートまたはグループコンテナ内のファイルを使用します。

import Foundation
let shared = UserDefaults(
    suiteName: "group.com.example.app")
// App writes; widget reads the same suite.
_ = shared

Widgetの再読み込み

アプリのデータが変わったら、WidgetCenter.shared.reloadTimelines(ofKind:)(またはreloadAllTimelines())を呼び出してWidgetKitに更新を要求します。これにより、システムはプロバイダーに新しいタイムラインを要求します。

import WidgetKit
func refreshWidget() {
    WidgetCenter.shared.reloadTimelines(
        ofKind: "WeatherWidget")
}

確認問題

Widgetがホストアプリとデータを共有する方法を思い出してください。

まとめ

WidgetKitのWidgetを構築しました。

  • Widgetは独立したExtensionに配置し、Widgetに準拠してWidgetConfigurationを返します。
  • StaticConfigurationまたはAppIntentConfiguration、TimelineEntry、制約のあるSwiftUIビューを使用します。
  • supportedFamiliesを宣言し、widgetFamilyに応じて調整し、containerBackgroundを追加します。
  • App Groupを通じてデータを共有し、WidgetCenter.reloadTimelinesで更新します。

よくある質問

「WidgetKitウィジェットの構築」レッスンは無料ですか?

はい。「WidgetKitウィジェットの構築」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。

「WidgetKitウィジェットの構築」で何を学びますか?

タイムラインを使ってホーム画面ウィジェットを作成します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Swift Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「WidgetKitウィジェットの構築」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSwift Academyレッスンでコードを書いて実行できますか?

はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. WidgetKitウィジェットの構築
  2. タイムラインプロバイダーとスナップショット
  3. App Extensionsの概要
  4. App IntentsとShortcuts
← Swift Academyに戻る