RORK LABEN
MAX — Rork Maxはネイティブ Swiftアプリを生成。iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageに対応しますNATIVE — AR/LiDAR・Metalによる3D・ウィジェット・Dynamic Island・Live Activities・Siri Intents・HealthKitなど、ネイティブ機能を引き出せますRN — 標準のRorkはReact Native(Expo)でクロスプラットフォーム。素早く形にするならこちらが向いていますCHOICE — 手早さならReact Native版、Appleのハード/OS統合を活かすならRork Maxという棲み分けが現実的ですPRICE — Rorkは無料で開始でき有料は月$25から、Rork Maxは月$200ですFLOW — 作りたいアプリを平易な言葉で説明すると、ストアに配信できる動くコードが生成されますMAX — Rork Maxはネイティブ Swiftアプリを生成。iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageに対応しますNATIVE — AR/LiDAR・Metalによる3D・ウィジェット・Dynamic Island・Live Activities・Siri Intents・HealthKitなど、ネイティブ機能を引き出せますRN — 標準のRorkはReact Native(Expo)でクロスプラットフォーム。素早く形にするならこちらが向いていますCHOICE — 手早さならReact Native版、Appleのハード/OS統合を活かすならRork Maxという棲み分けが現実的ですPRICE — Rorkは無料で開始でき有料は月$25から、Rork Maxは月$200ですFLOW — 作りたいアプリを平易な言葉で説明すると、ストアに配信できる動くコードが生成されます
記事一覧/開発ツール
開発ツール/2026-06-18上級

Rork Max の通知を長押しすると自前の画面が出る — Notification Content Extension の実装

Rork Max が生成した Swift アプリに Notification Content Extension を足し、通知を展開したときだけ自前の UI を描く実装をまとめました。Service Extension との役割分担、ボタンで通知内 UI を更新する手順、App Group での状態共有、出ないときの確認順を実コードで整理します。

Rork Max172Notification Content Extensionプッシュ通知17UserNotificationsSwift28App Group4

プレミアム記事

毎朝ひとつだけ作品を届ける、小さな個人開発アプリを App Store で運用しています。プッシュ通知に画像は出せるようになったのですが、ある日ユーザーから「通知から直接その日の絵を保存したい」という要望が届きました。通知をタップして本体を開かせるのではなく、通知の中で完結させたい。これは標準のリッチ通知では届かない領域でした。

通知の見た目を変える仕組みには二つあり、最初に私自身がここを混同していたので、まずその切り分けから始めます。Rork Max はネイティブ Swift を生成してくれますが、「通知の中に自前の画面を描く」という部分は、生成された雛形をそのまま動かすだけでは出てきません。Extension のターゲット追加、カテゴリの一致、メモリの制約といった泥臭い箇所を、自分のアプリに組み込んだ順番で書いていきます。

Service Extension と Content Extension は役割が違う

UserNotifications には拡張ポイントが二つあります。混同すると「画像は出るのにボタンが効かない」「UI を作ったのに表示されない」という迷路にはまります。

拡張動くタイミングできることできないこと
Notification Service Extension通知が届いた直後・表示される前ペイロードの書き換え、画像など添付の取得、復号UI を描くこと・ユーザー操作に反応すること
Notification Content Extensionユーザーが通知を展開したとき自前の ViewController で UI を描く、ボタンで UI を更新する届く前のペイロード加工(それは Service 側の仕事)

整理すると、画像をダウンロードして通知に添付するところまでは Service Extension の担当、その通知を長押し(または下スワイプ)で展開したときに「保存」ボタン付きの自前カードを描くのが Content Extension の担当です。今回の要望は後者でした。二つは併用でき、実際の本番ではセットで使うことが多いと感じています。

カテゴリという「合言葉」で結びつける

Content Extension が表示されるかどうかは、すべてカテゴリ識別子の一致で決まります。流れはこうです。

  1. 本体アプリで UNNotificationCategory を登録する(識別子と、付けたいアクションボタン)
  2. プッシュのペイロードに同じ識別子を category として載せる
  3. Content Extension の Info.plist の UNNotificationExtensionCategory に同じ識別子を書く

この三つが一文字でもずれると、カスタム UI は黙って出ません。エラーも出ないので、最初の失敗はたいていここです。

本体アプリ側の登録は、起動時に一度だけ行います。

import UserNotifications
 
enum NotificationSetup {
    static func registerCategories() {
        let save = UNNotificationAction(
            identifier: "SAVE_PICK",
            title: "保存",
            options: []
        )
        let openShuffle = UNNotificationAction(
            identifier: "SHUFFLE_PICK",
            title: "別の作品を見る",
            options: []
        )
        let dailyPick = UNNotificationCategory(
            identifier: "DAILY_PICK",          // ← この合言葉が要
            actions: [save, openShuffle],
            intentIdentifiers: [],
            options: []
        )
        UNUserNotificationCenter.current()
            .setNotificationCategories([dailyPick])
    }
}

送信するペイロード側は、同じ category を持たせ、Service Extension に画像を取りに行かせるため mutable-content も立てておきます。

{
  "aps": {
    "alert": { "title": "今日の一枚", "body": "本日の作品が届きました" },
    "mutable-content": 1,
    "category": "DAILY_PICK"
  },
  "image_url": "https://example.com/picks/2026-06-18.jpg"
}

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

この記事の続きを読む

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

この記事で得られること
Service Extension(届く前に書き換える)と Content Extension(展開時に描く)の役割を切り分け、自分のアプリでどちらが必要かを判断できます
UNNotificationExtensionCategory・UserInteractionEnabled など Info.plist の4キーと、ボタン押下で completion(.doNotDismiss) を返して通知内 UI を更新する実コードが手に入ります
App Group 経由で「保存」状態を本体アプリと共有する設計と、カスタム UI が出ない6つの原因を確認する順番がわかります
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

開発ツール2026-06-18
Rork Max の Swift アプリを String Catalog で多言語運用する
Rork Max が生成する Swift アプリを、.xcstrings(String Catalog)を軸に複数言語へ広げる運用設計をまとめました。文字列の抽出から複数形の扱い、翻訳の流し込み、崩れの検査まで、多言語アプリを長く回してきた立場での勘どころを残します。
開発ツール2026-06-17
Rork Max のネイティブ Swift ウィジェットで日替わり表示が止まる — TimelineProvider の更新予算を設計する
Rork Max が生成するネイティブ Swift のホーム画面ウィジェットは、TimelineProvider の更新予算を理解しないと日替わり表示が翌日以降に止まります。reloadPolicy と App Group、ディープリンクまでを実アプリ設計の観点で整理します。
開発ツール2026-06-16
Rork Max のネイティブアプリの中身を iPhone の検索に載せる — Core Spotlight で「探されるアプリ」にする実装
Rork Max が生成するネイティブ Swift アプリのコンテンツを Core Spotlight に索引し、iPhone の検索からアプリ内の特定画面へ直接たどり着ける導線を実装します。索引の登録・更新・削除と、検索結果が古くなる本番の落とし穴を個人開発目線で整理しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →