RORK LABEN
ENGINE — Rork MaxはClaude CodeとClaude Opus 4.6を基盤に、ネイティブSwiftアプリを直接生成しますCORE ML — Rork MaxからCore MLの端末内推論・HealthKit・HomeKit・NFC・App Clipsといった機能に手が届きますSEED — Rorkは2026年4月にLeft Lane Capital主導で$15Mのシードを調達し、Peak XVやa16z Speedrunが参加しましたM&A — Rorkはアプリビルダー Paperline を買収し、エンジニアリング人材の獲得を目的に買収を継続する方針ですMARKET — Gartnerは2026年末までに新規アプリの75%がローコードまたはノーコードで作られると予測していますGROWTH — ノーコードAI市場は2024年の$4.9Bから2029年に$24.8Bへ、年38.2%の成長が見込まれていますENGINE — Rork MaxはClaude CodeとClaude Opus 4.6を基盤に、ネイティブSwiftアプリを直接生成しますCORE ML — Rork MaxからCore MLの端末内推論・HealthKit・HomeKit・NFC・App Clipsといった機能に手が届きますSEED — Rorkは2026年4月にLeft Lane Capital主導で$15Mのシードを調達し、Peak XVやa16z Speedrunが参加しましたM&A — Rorkはアプリビルダー Paperline を買収し、エンジニアリング人材の獲得を目的に買収を継続する方針ですMARKET — Gartnerは2026年末までに新規アプリの75%がローコードまたはノーコードで作られると予測していますGROWTH — ノーコードAI市場は2024年の$4.9Bから2029年に$24.8Bへ、年38.2%の成長が見込まれています
記事一覧/アプリ開発
アプリ開発/2026-06-14上級

WidgetKit のタイムラインを更新予算と向き合って設計する — 壁紙アプリのウィジェットが止まった理由

ホーム画面ウィジェットが「夕方になると更新されなくなる」のはなぜか。WidgetKit のタイムライン設計を、更新予算・リロードポリシー・エントリ密度の3点から整理しました。TimelineProvider の実コード、予算を使い切らないエントリ設計、relevance による優先度づけまで、個人開発で6本の壁紙アプリを運用しながら詰めた知見を共有します。

WidgetKit10TimelineProvideriOS106Rork Max219ウィジェット7パフォーマンス30

プレミアム記事

6本の壁紙アプリを個人開発で運用していて、ある時期から「ホーム画面ウィジェットの今日の一枚が、夕方以降は昨日のままになる」という報告が増えました。シミュレータでは正しく切り替わるのに、実機では夕方で止まる。この差を生んでいたのが、WidgetKit の更新予算という見えにくい仕組みでした。

ウィジェットはアプリと違い、好きなタイミングで好きなだけ描き直せるものではありません。システムが1日あたりの更新回数におおまかな予算を割り当てており、それを使い切ると、翌日まで更新が来なくなります。この前提を知らずにタイムラインを組むと、午前中に予算を食い尽くして午後は沈黙する、という今回の症状になります。

タイムラインは「未来の予定表」である

WidgetKit の考え方の中心は、ウィジェットが「いま何を表示するか」を毎回問い合わせるのではなく、「これからしばらくの表示予定」をまとめて提出する点にあります。TimelineProvider が返す Timeline は、複数の TimelineEntry を時刻つきで並べた予定表です。

システムはこの予定表に従って、指定時刻になったら次のエントリへ自動で切り替えます。つまり、未来の表示を先に計算して束ねて渡せば、その間システムへの問い合わせ(=予算消費)は発生しません。ここを理解すると、設計の方向性が決まります。

1エントリずつ刻むと予算が枯れる

最初に私がやってしまったのが、1時間ごとに1エントリだけ返し、.atEnd で「終わったらまた取りに来て」と繰り返す実装でした。これは一見正しく動きますが、リロードのたびに予算を消費するため、変化の多い日には昼過ぎで予算が尽きます。

正しくは、1回のタイムライン生成で未来の複数エントリをまとめて返します。たとえば1日分の切り替えを24本のエントリとして先に計算し、それを1つの Timeline に詰めて返せば、その日のうちはほぼ追加の問い合わせなしで回ります。

import WidgetKit
import SwiftUI
 
struct WallpaperProvider: TimelineProvider {
    func placeholder(in context: Context) -> WallpaperEntry {
        WallpaperEntry(date: Date(), imageName: "placeholder")
    }
 
    func getSnapshot(in context: Context, completion: @escaping (WallpaperEntry) -> Void) {
        completion(WallpaperEntry(date: Date(), imageName: todaysImageName()))
    }
 
    func getTimeline(in context: Context, completion: @escaping (Timeline<WallpaperEntry>) -> Void) {
        var entries: [WallpaperEntry] = []
        let calendar = Calendar.current
        let now = Date()
 
        // 未来 12 本を 2 時間刻みでまとめて生成し、束ねて返す
        for hourOffset in stride(from: 0, to: 24, by: 2) {
            guard let entryDate = calendar.date(byAdding: .hour, value: hourOffset, to: now) else { continue }
            let name = imageName(for: entryDate)
            entries.append(WallpaperEntry(date: entryDate, imageName: name))
        }
 
        // 翌日の頭で一度だけ次のタイムラインを取りに来る
        let tomorrow = calendar.date(byAdding: .day, value: 1, to: now)!
        completion(Timeline(entries: entries, policy: .after(tomorrow)))
    }
}

この実装の肝は、for ループで未来のエントリをまとめて作っている点と、policy.after(tomorrow) にして「次に取りに来るのは明日でよい」と宣言している点です。これで1日あたりの問い合わせ回数が劇的に減り、夕方の沈黙が消えました。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
1日の更新予算を使い切らないために、1エントリずつ刻むのではなく未来を束ねて返す TimelineProvider の実装を、動く Swift で持ち帰れる
.atEnd・.after・.never の3つのリロードポリシーをどの種類のウィジェットで選ぶか、判断基準を表で確認できる
「夕方に更新が止まる」「タップしても古い画像のまま」という個人開発で実際に起きた2つの症状の原因と直し方がわかる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

アプリ開発2026-07-03
Rork Max アプリで通信の切断と復帰に強くする — NWPathMonitor によるオフライン検知と再送設計
Rork Max のネイティブ Swift アプリで、電波が切れても壊れない通信設計を NWPathMonitor で組み立てます。オフラインの検知、Low Data Mode やモバイル回線の判定、復帰時の自動再送キューまで、動く Swift コードで示します。
アプリ開発2026-07-03
Rork Max アプリでダウンロードをアプリ終了後も続ける — バックグラウンド URLSession の設計と再起動復帰
Rork Max のネイティブ Swift アプリで、アプリがサスペンド・終了されてもダウンロードを OS 側で継続させるバックグラウンド URLSession の設計を解説します。再起動復帰・resumeData・isDiscretionary の実測挙動まで動くコードで示します。
アプリ開発2026-07-01
Rork Max のネイティブ Swift で SharePlay を組む — 二人の画面を同じ状態で動かす設計
GroupActivities を使い、FaceTime 越しに二人の画面を同じ状態で動かす SharePlay を Rork Max のネイティブ Swift で組む実装メモです。GroupActivity の宣言、GroupSession への参加、GroupSessionMessenger での状態同期、遅延と競合の扱い、そして React Native 側から橋渡しするときの境界設計まで、実際に詰まった点を添えてまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →