Notification Extension: 基本概念、拡張タイプ、設定方法

著者: IT Sectr 公開日: 2026-03-20 読了時間: 8 分

Notification Extensionは、プッシュ通知をユーザーに表示する前にその内容と外観を変更できるiOSのメカニズムです。拡張機能はオペレーティングシステム側で別プロセスとして動作し、UNNotificationServiceExtensionが受信コンテンツを処理し、UNNotificationContentExtensionがインターフェースを管理します。Apple Developer Documentation、2026によると、Service Extensionは通知表示前にタスクを実行するために最大30秒与えられます。この制限は添付ファイルのダウンロードやデータの復号化において重要です。

重要ポイント

  • Service Extension — 表示前に通知をインターセプトし、テキストの変更、メディアの追加、30秒の制限内でのデータ復号化が可能。
  • Content Extension — ストーリーボードやSwiftUIを使用して、カスタムUI、ボタン、タップ処理を備えたカスタム通知インターフェースを作成。
  • メディア添付 — 画像、動画、音声はContent Extensionに渡す前にService ExtensionでUNNotificationAttachmentを介して追加。
  • 登録 — 両方の拡張機能はInfo.plistで通知カテゴリとNSExtensionPointIdentifierを指定して個別のターゲットとして登録。
  • 制限事項 — 拡張機能はメインアプリケーションにアクセスできず、50 MBのメモリ制限のある隔離されたサンドボックスで動作。

Notification Extensionとは

Notification Extensionは、プッシュ通知の標準動作を拡張し、コンテンツの変更とインターフェースのカスタマイズを可能にするiOSソフトウェアコンポーネントです。システムが標準形式で表示する通常の通知とは異なり、拡張機能は開発者が表示前にコンテンツに影響を与え、独自のユーザーインターフェースを作成することを可能にします。

2種類の通知拡張機能

Appleは異なる目的のために2種類のNotification Extensionを提供しています。UNNotificationServiceExtensionは受信ペイロードの処理を担当し、UNNotificationContentExtensionは表示を管理します。Service Extensionは通知が表示される前に実行され、Apple Developer Documentationによると最大30秒の制限された実行時間があります。Content Extensionはユーザーが通知と対話した後にアクティブになり、カスタムビューを表示します。

標準通知との違い

標準のiOSプッシュ通知は、JSONペイロードのalert、title、subtitleフィールドに基づいてシステムによって自動的に表示されます。Notification Extensionは制御をインターセプトします。Service Extensionは生のペイロードを受け取り、それを変更して表示のためにシステムに渡します。Content Extensionは標準のバナーを任意の制御要素を持つカスタムインターフェースに置き換えます。

拡張機能のライフサイクル

デバイスがmutable-content:1キーを持つプッシュ通知を受信すると、システムは別のプロセスでService Extensionを起動します。拡張機能のプロセスはメインアプリケーションから隔離され、50 MBのメモリ制限を持つ独自のサンドボックスを持ちます。処理が完了すると、拡張機能はcompletion handlerを呼び出し、変更されたUNNotificationContentを表示のためにシステムに渡します。

UNNotificationServiceExtension: コンテンツの変更

UNNotificationServiceExtensionは、ユーザーに表示する前にプログラムでプッシュ通知を変更するための主要なツールです。拡張機能は、ペイロードにmutable-content:1フラグが設定された通知を受信すると自動的にアクティブになります。30秒以内に、拡張機能はメディア添付ファイルのダウンロード、テキストの変更、暗号化データの復号化、コンテンツの強化を行うことができます。

UNNotificationServiceExtensionプロトコルのメソッド

拡張機能はUNNotificationServiceExtensionプロトコルから2つの主要なメソッドを実装します。didReceiveメソッドは生のUNNotificationRequestを持つ受信リクエストを受け取り、新しいUNNotificationContentでcompletion handlerを通じて変更を許可します。serviceExtensionTimeWillExpireメソッドはタイムアウトの1秒前にシステムによって呼び出されます。この中で処理を完了し、現在の(おそらく部分的な)結果を渡す必要があります。

例:通知への画像追加

サーバーがカスタムフィールドに画像URLを含むプッシュを送信するシナリオを考えます。Service Extensionはこの画像をネットワーク経由でダウンロードし、UNNotificationAttachmentを作成してコンテンツに追加します。UNNotificationAttachmentはローカルの画像、動画、または音声ファイルを受け入れ、自動的に拡張機能のサンドボックスにコピーします。添付ファイルを作成した後、拡張機能は更新されたコンテンツをシステムに渡します。

swift
class NotificationService: UNNotificationServiceExtension {

    override func didReceive(_ request: UNNotificationRequest,
        withContentHandler contentHandler:
        @escaping (UNNotificationContent) -> Void) {

        let userInfo = request.content.userInfo
        guard let imageURL = URL(string: userInfo["image-url"] as! String)
        else { contentHandler(request.content); return }

        let attachment = try! UNNotificationAttachment(
            identifier: "image", url: imageURL,
            options: [UNNotificationAttachmentOptionsTypeHintKey: "jpg"])

        let modifiedContent = request.content.mutableCopy()
            as! UNMutableNotificationContent
        modifiedContent.attachments = [attachment]
        contentHandler(modifiedContent)
    }

    override func serviceExtensionTimeWillExpire() {
        contentHandler?(bestAttemptContent ?? request.content)
    }
}

キャッシュと再利用

同じ添付ファイルを持つ通知が頻繁に送信される場合、ダウンロードしたファイルをデバイスにキャッシュすることをお勧めします。FileManagerは、起動間で永続化される拡張機能のキャッシュディレクトリへのアクセスを提供します。これにより、後続の通知の処理時間が短縮され、ネットワーク負荷が軽減されます。Appleによると、キャッシュにより処理時間を完全なダウンロードの代わりに2〜5秒に短縮できます。

UNNotificationContentExtension: カスタムインターフェース

UNNotificationContentExtensionは、標準の通知バナーをInterface BuilderまたはSwiftUIで作成されたカスタムインターフェースに置き換えることを可能にします。拡張機能はユーザーが通知に対してアクション(タップ、スワイプダウン、3D Touch)を実行したときにアクティブになります。Content ExtensionはService Extensionによって既に処理されたコンテンツを受け取り、カスタムビューに表示します。

ストーリーボードと通知カテゴリ

各Content ExtensionはInfo.plistを介して1つ以上の通知カテゴリにリンクされます。カテゴリはサーバー側でAPNSペイロードのcategoryフィールドによって定義されます。システムは受信した通知のカテゴリに基づいて適切な拡張機能を自動的に選択します。インターフェースは標準のUIKitコンポーネントまたはSwiftUI Viewを使用してストーリーボードを介して構築されます。

ユーザーアクションの処理

Content ExtensionはUNNotificationActionで定義されたカスタムボタンとタップハンドラーをサポートします。UNNotificationActionはカテゴリ登録段階で作成され、UNTextInputNotificationActionを介してテキスト入力をサポートできます。ユーザーがボタンを押すと、拡張機能はアクション識別子とともにdidReceiveコールバックを受け取り、対応するロジック(URLを開く、サーバーにリクエストを送信する、インターフェースを更新する)を実行できます。

パフォーマンスの制限

Content Extensionは独自のランループと約50 MBのメモリ制限を持つ隔離されたプロセスで実行されます。拡張機能のパフォーマンスは、システムのウォッチドッグが制限を超えるとプロセスを終了するため重要です。Content Extension内での重い計算、大きな画像の読み込み、長時間のネットワークリクエストは避けることをお勧めします。

メディア添付とUNNotificationAttachment

UNNotificationAttachmentは、プッシュ通知にメディアファイル(画像、動画、音声、GIF)を追加するオブジェクトです。添付ファイルは、拡張機能のサンドボックス内にあるローカルファイルURLから作成されます。添付ファイルの最大サイズは10 MBを超えてはなりません。超えた場合、システムは作成時に添付ファイルを拒否します。

サポートされる形式

Appleはメディア添付ファイルに対して限られた形式のセットをサポートしています。画像 — JPEG、PNG、GIF(アニメーションを含む)、TIFF。動画 — MPEG、MP4、MOV、最大30秒の長さ。音声 — MP3、AAC、WAV、CAF。各形式について、UNNotificationAttachmentOptionsTypeHintKeyを介してタイプを指定でき、システムがファイルを正しく処理するのに役立ちます。

ネットワークからの添付ファイルのダウンロード

プッシュペイロードにはファイル自体ではなくURLのみが含まれるため、添付ファイルのダウンロードはService Extension内で行う必要があります。最大ダウンロード時間は30秒に制限されているため、最小限の設定でURLSessionを使用し、弱い信号ではダウンロードを無効にすることをお勧めします。添付ファイルが時間内に読み込まれない場合、通知はメディアなしで表示されます。これがシステムのデフォルト動作です。

Swiftでの実装例

画像をダウンロードして保存し、通知に追加する完全なNotification Extensionの例を見てみましょう。NotificationServiceはUNNotificationServiceExtensionを継承し、didReceiveメソッドをオーバーライドします。この例では、オプションフィールドの処理、添付ファイルの作成、変更されたコンテンツでのcompletion handlerの呼び出しを示しています。

swift
import UserNotifications

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(
        _ request: UNNotificationRequest,
        withContentHandler contentHandler:
        @escaping (UNNotificationContent) -> Void
    ) {
        self.contentHandler = contentHandler
        self.bestAttemptContent =
            (request.content.mutableCopy()
                as! UNMutableNotificationContent)

        guard let attachmentURLString =
            bestAttemptContent?.userInfo["attachment-url"] as? String,
            let url = URL(string: attachmentURLString)
        else {
            contentHandler(request.content)
            return
        }

        URLSession.shared.downloadTask(with: url) {
            [weak self] localURL, _, error in
            guard let localURL = localURL, error == nil
            else {
                contentHandler(request.content)
                return
            }
            let attachment = try! UNNotificationAttachment(
                identifier: "media", url: localURL)
            self?.bestAttemptContent?.attachments = [attachment]
            contentHandler(self?.bestAttemptContent
                ?? request.content)
        }.resume()
    }

    override func serviceExtensionTimeWillExpire() {
        if let content = bestAttemptContent {
            contentHandler?(content)
        }
    }
}

拡張機能のInfo.plist設定

拡張機能を正しく動作させるには、Info.plistで通知カテゴリを登録する必要があります。NSExtensionPointIdentifierキーはService Extensionの場合はcom.apple.usernotifications.service、Content Extensionの場合はcom.apple.usernotifications.contentに設定します。カテゴリはAppDelegateでアプリ起動時にUNUserNotificationCenterを介して定義され、拡張機能はペイロードに一致するカテゴリを持つ通知に対してのみアクティブになります。

よくある質問

Service ExtensionとContent Extensionの違いは何ですか?

Service Extensionは通知表示前にコンテンツを変更します。メディアの追加、テキストの変更、データの復号化を行います。Content Extensionはユーザー操作後に通知インターフェースをカスタムインターフェースに置き換えます。Service Extensionは表示前に動作し、Content Extensionは表示後に動作します。

Service Extensionの処理時間はどのくらいですか?

システムはdidReceiveでのコード実行に30秒を割り当てます。この時間内に処理が完了しない場合、serviceExtensionTimeWillExpireが呼び出され、現在の結果を渡す必要があります。添付ファイルのダウンロードを考慮して10〜15秒以内に収めることをお勧めします。

Content ExtensionでSwiftUIを使用できますか?

はい、SwiftUIはiOS 16以降のContent Extensionでサポートされています。ViewはUIHostingControllerにラップされてストーリーボードに追加されます。ただし、メモリ制限のため、SwiftUIは最小限の要素を持つシンプルなインターフェースにのみ使用することをお勧めします。

添付ファイルのダウンロードエラーはどのように処理しますか?

ダウンロードエラーまたはタイムアウトの場合、添付ファイルなしで元のコンテンツをcompletion handlerに渡すだけです。システムは通知をメディアなしで標準形式で表示します。診断のためにOSLogでエラーを記録しますが、通知の表示をブロックしないでください。

Notification Extensionのメモリ制限はどのくらいですか?

拡張機能は約50 MBの制限を持つ隔離されたプロセスで実行されます。制限を超えると、システムはウォッチドッグを介してプロセスを強制終了します。大きなファイルの読み込み、メモリ内の画像の保存、URLSessionでのリークを避けてください。

まとめ

  • Notification Extension — プッシュ通知を変更するためのiOSメカニズム。Service Extension(コンテンツ)とContent Extension(インターフェース)を含む。
  • Service Extensionは30秒の制限で通知表示前にペイロードを処理し、メディア添付ファイルの追加やデータの復号化が可能。
  • Content ExtensionはUIKitまたはSwiftUIを介して標準バナーをカスタムインターフェースに置き換え、インタラクティブなボタンをサポート。
  • UNNotificationAttachmentは通知に画像、動画、音声を追加し、JPEG、PNG、MP4、MP3などの形式をサポート。
  • 拡張機能の登録は、アクティベーションのためにNSExtensionPointIdentifierと通知カテゴリを指定してInfo.plistを介して行われる。
  • 制限事項 — 50 MBのメモリ制限、メインアプリケーションにアクセスできない隔離されたサンドボックス、制限された実行時間。
  • Notification Extensionはリッチなユーザー通知を作成するための重要なツールであり、iOSでのプッシュ通信のエンゲージメントと機能性を向上させる。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください