Notification Service Extensionとは、iOSで表示前にコンテンツを処理する方法

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

Notification Service Extensionは、ユーザーに表示される前にプッシュ通知をインターセプトし、コンテンツを変更できるようにするiOS拡張機能です。この拡張機能は、暗号化されたデータを復号し、メディア添付ファイルをダウンロードし、テキストを変更したり、カスタムフィールドを追加したりできます。Apple Developer, 2025によると、Notification Service Extensionはバックグラウンドでタスクを完了するために最大30秒の時間があります。

重要なポイント

  • Notification Service Extension — 表示前にプッシュ通知を処理するためのiOS拡張機能です。
  • 拡張機能はUNNotificationServiceExtensionを継承し、didReceiveメソッドを実装します。
  • データのダウンロードと処理のために最大30秒のバックグラウンド実行が可能です。
  • 主なユースケース:ペイロードの復号、画像や動画のダウンロード、コンテンツの検証。
  • 拡張機能は通知の表示を遅延させたり、contentHandlerを介して完全にキャンセルしたりできます。

Notification Service Extensionとは

Notification Service Extensionは、プッシュ通知が表示される前に実行されるiOSのアプリ拡張機能です。サーバーが最小限のペイロードを送信し、拡張機能が画像のダウンロード、データの復号、テキストの置換などのコンテンツを追加します。ユーザーは既に処理された通知を表示します。

仕組み

iOSがプッシュ通知を受信すると、システムはアプリに拡張機能が存在するかどうかを確認します。拡張機能が登録されている場合、iOSはそれをバックグラウンドプロセスで起動し、didReceive(_:withContentHandler:)メソッドを介して通知コンテンツを渡します。拡張機能はコンテンツを処理し、変更されたコンテンツでcontentHandlerを呼び出します。拡張機能が30秒以内に完了しない場合、システムは元の通知を表示します。

Service Extensionを使用すべき場合

Service Extensionは、通知コンテンツがデバイス上での処理を必要とするシナリオで必要です。安全な通信:サーバーが暗号化されたペイロードを送信し、拡張機能がローカルで復号します。リッチメディア通知:サーバーが画像URLを送信し、拡張機能がダウンロードして添付します。動的ローカライゼーション:拡張機能がデバイスの言語でテキストを置換します。

シナリオ拡張機能なし拡張機能あり
画像サポートされていませんダウンロードされて表示されます
暗号化サーバーが鍵を保持デバイス上で復号
テキストサーバーで固定動的置換
検証チェックされません悪意のある通知をキャンセル

制限事項と実行時間

Notification Service Extensionは制限された環境で動作します。最大実行時間は30秒です。拡張機能は(App Groupを除く)メインアプリのストレージにアクセスできません。拡張機能のサイズは50 MBに制限されています。時間を超過すると、システムは元のコンテンツでcontentHandlerを呼び出し、すべての変更が失われます。

拡張機能の作成とInfo.plistの設定

Xcodeでは、Notification Service ExtensionはNotification Service Extensionタイプの新しいtargetを作成して追加します。XcodeはUNNotificationServiceExtensionを継承するテンプレートNotificationServiceクラスを生成し、didReceiveとserviceExtensionTimeWillExpireの2つのメソッドを持ちます。

プロジェクトへのtargetの追加

Xcodeで、File → New → Target → Notification Service Extensionを選択します。名前(例:PushNotificationService)を入力し、Swift言語を選択します。targetがメインアプリに追加され、正しい署名があることを確認します。作成後、NotificationService.swiftクラスが基本的な実装とともに生成されます。

拡張機能のInfo.plist構造

拡張機能のInfo.plistには、NSExtensionキーとサブキーのNSExtensionPointIdentifier(com.apple.usernotifications.service)およびNSExtensionPrincipalClass(コントローラ名)が含まれます。さらに、拡張機能のアクティベーションルールを持つNSExtensionAttributesを指定できます。Xcodeはこれらの設定を自動的に生成します。

基本的な拡張機能の例

基本的な実装はdidReceiveをオーバーライドし、通知コンテンツを変更してcontentHandlerを呼び出します。処理に時間がかかりすぎる場合、serviceExtensionTimeWillExpireが呼び出され、現在の状態で作業を完了する必要があります。

swift
import UserNotifications

class NotificationService: UNNotificationServiceExtension {

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

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

        if let bestAttemptContent = bestAttemptContent {
            bestAttemptContent.title = "[処理済み] \(bestAttemptContent.title)"
            contentHandler?(bestAttemptContent)
        }
    }

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

暗号化されたペイロードの復号

Service Extensionの主な用途の1つは、デバイス上で通知コンテンツを復号することです。サーバーが暗号化されたペイロードを送信し、拡張機能がKeychainまたはApp Groupに保存された鍵を使用して復号します。これにより、送信中にコンテンツが傍受されるのを防ぎます。

安全な配信アーキテクチャ

サーバーは対称鍵(AES-256)を使用して通知本文を暗号化します。暗号化鍵はクライアントとサーバー間で事前に合意されます。拡張機能はペイロードのdataフィールドで暗号化された文字列を受け取り、復号して通知フィールドに代入します。ユーザー鍵は認証後にKeychainから取得できます。

swift
override func didReceive(
    request: UNNotificationRequest,
    withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
    guard let content = request.content.mutableCopy()
        as? UNMutableNotificationContent else {
        handler(request.content)
        return
    }

    guard let encryptedData = content.userInfo["encrypted_data"]
        as? String else {
        handler(content)
        return
    }

    let decrypted = CryptoService.decrypt(encryptedData)
    content.body = decrypted.body
    content.title = decrypted.title
    handler(content)
}

安全な鍵の保存

復号鍵は拡張機能のコードやNSUserDefaultsに保存してはいけません。アプリと拡張機能の両方が鍵を読み取れるように、App Groupを介したアクセスを持つiOS Keychainを使用してください。クライアントでの鍵生成には、AES-256-GCMアルゴリズムのSecurity.frameworkを使用します。

メディア添付ファイルのダウンロードと添付

Notification Service Extensionの最も一般的な用途は、通知に表示する画像、GIF、動画をダウンロードすることです。サーバーがメディアファイルのURLを送信し、拡張機能がそれをダウンロードして一時ディレクトリに保存し、UNNotificationAttachmentを作成します。

メディアのダウンロードと添付のプロセス

拡張機能は通知ペイロードフィールドから画像URLを受け取ります。URLSessionを使用して、拡張機能はファイルを一時ディレクトリにダウンロードします。ダウンロードが完了すると、ローカルURLを持つUNNotificationAttachmentが作成されます。添付ファイルは変更されたコンテンツに渡されます。iOSは自動的に標準インターフェースまたはNotification Content Extensionで画像を表示します。

swift
private func downloadAndAttachMedia(
    content: UNMutableNotificationContent,
    mediaUrl: String,
    handler: @escaping (UNNotificationContent) -> Void
) {
    guard let url = URL(string: mediaUrl) else {
        handler(content)
        return
    }

    let task = URLSession.shared.downloadTask(with: url) { localUrl, _, error in
        guard let localUrl = localUrl, error == nil else {
            handler(content)
            return
        }

        let attachment = try? UNNotificationAttachment(
            identifier: "media",
            url: localUrl,
            options: nil
        )

        if let attachment = attachment {
            content.attachments = [attachment]
        }
        handler(content)
    }
    task.resume()
}

サポートされているメディア形式

iOSは通知表示のために以下の形式をサポートしています:JPEG、PNG、GIF(静的)、50 MBまでのMPEG-4動画。オーディオファイルには、MP3、AAC、ALACがサポートされています。重要:すべてのメディアファイルは30秒の制限内でダウンロードする必要があります。大きなファイルの場合は、サーバー側のトリミングやプログレッシブローディングを推奨します。

時間管理とフォールバックシナリオ

30秒の制限の管理は、Notification Service Extensionを開発する際の重要なタスクです。拡張機能が時間内に処理を完了しない場合、システムはserviceExtensionTimeWillExpireを呼び出し、元のコンテンツを表示します。各処理タイプに対してフォールバックシナリオを提供する必要があります。

優先順位戦略

タスクを優先順位に従って分割します。最初に重要な変更(復号、基本的なローカライゼーション)を実行します。オプションの改善(画像のダウンロード、テキストの拡充)は後回しにします。ネットワークリクエストにはタイムアウト付きのURLSessionを使用して、制限時間全体を1つの操作に費やさないようにします。

エラー時のフォールバック

画像のダウンロードが失敗した場合やペイロードの復号がエラーを返した場合、拡張機能は元のコンテンツでcontentHandlerを呼び出す必要があります。contentHandlerを呼び出さずに拡張機能を終了しないでください。通知が失われます。安全なフォールバックは常に拡張機能コードに組み込む必要があります。

swift
override func didReceive(
    request: UNNotificationRequest,
    withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
    let content = (request.content.mutableCopy()
        as? UNMutableNotificationContent) ?? request.content

    // クリティカルタスク:復号
    var decryptedContent = tryDecryptPayload(content)

    // オプションタスク:メディア
    guard let mediaUrl = decryptedContent.userInfo["media_url"]
        as? String else {
        handler(decryptedContent)
        return
    }

    downloadAndAttachMedia(
        content: decryptedContent,
        mediaUrl: mediaUrl,
        handler: handler
    )
}

拡張機能のテスト

Notification Service Extensionをテストするには、Xcodeを使用します:拡張機能のtargetを選択し、シミュレーターで実行し、ターミナルまたはFirebase Consoleを介してプッシュ通知を送信します。os_logを使用して処理の各段階をログ記録します。これにより、タイミングやダウンロードの問題を診断するのに役立ちます。

よくある質問

拡張機能が30秒以内に完了しないとどうなりますか?

システムはserviceExtensionTimeWillExpireを呼び出し、その後元の通知を変更せずに表示します。ダウンロードされたすべてのファイルと変更は破棄されます。

拡張機能から通知の表示をキャンセルできますか?

はい、空のコンテンツ(空のフィールドのUNNotificationContent)でcontentHandlerを呼び出すと、通知は表示されません。これはスパム通知や不正なデータをフィルタリングするために使用されます。

メディアダウンロードのための認証トークンを渡すには?

トークンは通知ペイロードのuserInfoで渡すか、App Groupを介してKeychainから取得できます。拡張機能のUserDefaultsにトークンを保存することは推奨されません。

拡張機能に特別な証明書設定は必要ですか?

拡張機能はメインアプリと同じ開発者証明書で署名する必要があります。本番環境では、Push Notifications機能が有効な本番証明書が必要です。

実際のデバイスで拡張機能をデバッグするには?

デバイスをXcodeに接続し、実行スキームで拡張機能のtargetを選択し、Firebase Consoleを介してプッシュ通知を送信します。拡張機能のブレークポイントはメインアプリと同じように機能します。

まとめ

  • Notification Service Extension — 表示前にプッシュ通知をバックグラウンド処理するためのiOS拡張機能です。
  • 最大実行時間は30秒で、それを超えるとシステムは元のコンテンツを表示します。
  • 主なユースケース:ペイロードの復号、メディアのダウンロード、コンテンツの検証とローカライゼーション。
  • 拡張機能はUNNotificationServiceExtensionを継承し、didReceiveとserviceExtensionTimeWillExpireメソッドを持ちます。
  • メディアのダウンロードにはURLSessionを、鍵の保存にはiOS Keychainを使用します。
  • 常にフォールバックを提供し、エラー時には元のコンテンツでcontentHandlerを呼び出します。
  • 通知を完全に制御するために、Service ExtensionとContent Extensionを組み合わせて使用します。

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

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

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

こちらもお読みください