◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Expo SDK 58 が 10/15 に正式リリースされました(Beta は 09/15 から)。上げる前に依存の対応状況を確認しましょう●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Expo SDK 58 が 10/15 に正式リリースされました(Beta は 09/15 から)。上げる前に依存の対応状況を確認しましょう●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/開発ツール
⬡ 開発ツール/2026-06-03上級

コントロールセンターに壁紙シャッフルを置く — Rork(Expo) アプリの ControlWidget 実装と iOS 26 での作り直し

iOS 18 で開放されたコントロールセンターのカスタムコントロールを、Rork で作った React Native 製の壁紙アプリに足すまでの実装メモです。App Group 共有・AppIntent・config plugin に加え、iOS 26 の accented rendering で作り直した際の判断も残しました。

iOS 265ControlWidgetApp Intents6Expo219壁紙アプリ28

✦ プレミアム記事

「ロック解除しなくても、今日の壁紙を変えたい」——これは私が運用している壁紙アプリのひとつ『綺麗な壁紙』のレビュー欄に、iOS 18 が出た直後から少しずつ増えてきた要望でした。壁紙や癒し系のユーティリティは「アプリを開く」という一手間が地味に重く、開かれない日はそのまま広告も表示されません。

iOS 18 で、コントロールセンターにサードパーティ製のコントロールを置けるようになりました。アプリを開かずに、画面右上から引き下ろした先のボタンひとつで処理を走らせられます。壁紙アプリにとって、これは「開かれない日」を減らす数少ない正攻法です。

当時 Rork で生成した React Native(Expo)製アプリに後付けした実装を、先日 iOS 26 世代に合わせて作り直しました。当時のメモに、今の判断を重ねて残しておきます。

ControlWidget が壁紙アプリと噛み合う理由

カスタムコントロールは WidgetKit の一部として実装します。ホーム画面ウィジェットの親戚で、ControlWidget というプロトコルに準拠した小さな拡張ターゲットを作ると、ユーザーが「設定 → コントロールを追加」から自分のアプリのコントロールをコントロールセンターに置けるようになります。

ボタン型(ControlWidgetButton)とトグル型(ControlWidgetToggle)の2種類があり、壁紙シャッフルはボタン型が向いています。押した瞬間に AppIntent が走り、次の壁紙を選んで UserDefaults に書き込む、という流れです。AdMob の収益は表示回数に連動しますから、「アプリ起動」という重い導線の手前に、もう一段軽いタッチポイントを作れる意味は小さくありません。月あたりの起動回数が数%でも増えれば、ユーティリティアプリの薄い単価でも効いてきます。

ただし、コントロール自体が壁紙を「設定」できるわけではありません。iOS はサードパーティアプリにロック画面・ホーム画面壁紙の直接変更を許していないからです。ここは正直に設計を割り切る必要があります。私が採った方針は「コントロールで次の1枚を確定 → ショートカット or 共有シートで実際の設定はユーザーが行う」という現実解でした。コントロールが担うのは『今日の1枚を決める』ところまでです。

全体構成 — App Group を背骨にする

Rork(Expo)製アプリの本体は JavaScript 層で動きますが、ControlWidget は別プロセスのネイティブ拡張として動きます。両者は直接メモリを共有できないため、App Group を介した UserDefaults 共有が背骨になります。

構成要素は次の3つです。

  1. メインアプリ(Expo / React Native)— 壁紙のインデックスを App Group の UserDefaults に書く
  2. Control Extension(Swift / WidgetKit)— ControlWidget と AppIntent を持つ新規ターゲット
  3. App Group(group.design.dolice.wallpaper のような識別子)— 両者の共有ストレージ

この順で組むと、データの流れが一方向に整理されます。JS 側が「壁紙の総数」と「現在地」を共有ストレージへ書き、AppIntent 側がそれを読んでインデックスを進める、という分担です。

識別子は必ず定数へ切り出します。作り直しのときに最初にやったのがこれでした。

enum WallpaperControlKind {
    static let appGroup = "group.design.dolice.wallpaper"
    static let shuffle = "design.dolice.wallpaper.shuffle"
    static let dailyShuffle = "design.dolice.wallpaper.dailyShuffle"
}
✦

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

この記事の続きを読む

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

この記事で得られること
✦ControlWidget と AppIntent でコントロールセンターから1タップ壁紙を切り替える実装(Swift 約40行・kind 定数の切り出しまで込み)
✦状態を持たせたい場合の ControlWidgetToggle + ControlValueProvider + SetValueIntent の3点セットと、ボタン型との使い分け表
✦App Group 経由で Rork(Expo) 製 JS 層とネイティブ拡張の状態を共有する構成と、prebuild で設定が消えない config plugin の書き方
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

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

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

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

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

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

関連記事

⬡ 開発ツール2026-04-23
Rork アプリに Siri と Shortcuts を統合する — App Intents の Expo 実装と失敗しない設計
Rork で作った React Native アプリに Siri Shortcuts と App Intents を組み込む実装ガイド。Expo Config Plugin で native モジュールをブリッジし、AppShortcut・Entity Query・Donations・Control Center ウィジェットまで本番運用を見据えて解説します。
⬡ 開発ツール2026-10-15
EXPO_PUBLIC_ の値が、開発では読めて本番だけ undefined になる書き方を、変換結果で見分けます
API の URL が開発中は読めるのに、ビルドした途端に undefined になる。原因は process.env の書き方でした。babel-preset-expo の変換結果を開発・本番で並べ、置き換わる書き方と残ってしまう書き方を表にしました。
⬡ 開発ツール2026-10-13
リリース前に、書き出した Expo バンドルの中から自分の鍵を探してみる
ソースに鍵がなくても、出来上がったアプリの中に鍵が残ることがあります。Expo SDK 57 で実際に expo export を実行し、バンドルの中身を grep と 60 行ほどの Node スクリプトで調べて、見つかる鍵と見つからない鍵の違いを確かめました。