Notification Payload — JSON構造とパーシング

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

Notification Payload は、サーバーが APNS を通じて iOS デバイスに送信する JSON 構造体であり、push 通知の内容と受信時の動作を定義します。ペイロードには、テキスト、音、バッジ、メディア添付、バックグラウンド処理を制御する必須およびオプションのキーが含まれます。Apple Developer Documentation, 2026によると、一般的な通知の場合、最大ペイロードサイズは 4096 バイト、VoIP push の場合は 5120 バイトであり、転送できるデータ量に厳格な制限を設けています。

まとめ

  • aps 構造 — alert、badge、sound、content-available のキーをもつ必須のディクショナリで、通知の視覚的および音声の動作を定義します。
  • サイズ制限 — APNS の最大ペイロードサイズは 4096 バイト、VoIP push は 5120 バイトです。これを超えると Apple サーバーが拒否します。
  • カスタムフィールド — 追加データは aps と同じレベルで送信され、通知受信後に userInfo で利用可能です。
  • alert のローカライゼーション — title-loc-key、loc-key、loc-args のキーを使用することで、言語ごとに異なるペイロードを送ることなく、ローカライズされたテキストを表示できます。
  • Request-identifier — APNS 応答におけるカスタム識別子で、配信ステータスと Apple サーバーからのコールバックを追跡します。

Notification Payload とは

Notification Payload は、サーバーが APNS (Apple Push Notification Service) に送信し、iOS デバイスに配信する JSON オブジェクトです。ペイロードには、システムが通知を表示するために必要なすべてのデータが含まれます: タイトル、テキスト、音、バッジ、バックグラウンド処理のためのメタデータです。ペイロード構造は Apple によって厳格に規制されており、システムが正しく処理できるように必須のキーが含まれています。

push 配信におけるペイロードの役割

サーバーが APNS HTTP/2 API を通じて push 通知を送信するとき、リクエストには認証ヘッダーと JSON ボディ—ペイロードが含まれます。APNS はペイロードを検証します: JSON が不正だったり、サイズ制限を超えたりすると、Apple サーバーは 400 Bad Request エラーを返します。検証後、APNS はペイロードをデバイスに配信し、iOS がそれを解析して、通知の処理方法—バナーの表示、バックグラウンドタスクの実行、音の再生—を決定します。

ペイロード形式の進化

APNS ペイロード形式は、iOS 2 の簡単なテキストペイロードから、現代のバージョンでの複数コンポーネントからなる JSON 構造へと進化しました。iOS 10 では mutable-content によるメディア添付のサポートが登場し、iOS 12 では thread-id による通知グルーピングが追加され、iOS 15 ではライブアクティビティのための supports-live-activities が導入されました。今日では、ペイロードには、必要な通知の動作に応じて最大 15 の異なるキーを含めることができます。

APNS ペイロード構造: 必須およびオプションのキー

ルートオブジェクトには、aps ディクショナリとトップレベルのオプションのカスタムフィールドが含まれます。aps ディクショナリは唯一の必須要素ですが、その中には、通知のタイプに応じて、alert、badge、sound、content-available、mutable-content、interruption-level などの複数のキーの組み合わせが存在します。

aps キータイプ目的
alertString または Dictionary通知のテキスト、または title、subtitle、body、ローカライゼーションを含むオブジェクト
badgeNumberアプリアイコン上の数字; 0 はバッジを削除
soundString音声ファイル名またはシステム音の場合は default
content-availableNumber (1)バックグラウンド起動フラグ; 1 = サイレント push
mutable-contentNumber (1)コンテンツ変更のための Service Extension 起動フラグ
categoryStringボタンおよび Content Extension のカテゴリ識別子
thread-idString通知グルーピングのためのグループ識別子
interruption-levelString中断レベル: passive, active, time-sensitive, critical
relevance-scoreNumber (0–1)スマートランキングシステムのための通知優先度

alert キー: 文字列およびディクショナリ形式

alert キーは、簡単な文字列(それが通知ボディになります)または title、subtitle、body のフィールドをもつディクショナリです。ディクショナリ形式では、主なテキストとは区別してタイトルとサブタイトルを設定できます。ローカライズされた通知には、title-loc-key、title-loc-args、loc-key、loc-args のキーを使用します。これらは、アプリの Localizable.strings を参照します。これにより、特定の言語のテキストなしでペイロードを送信できます—アプリが翻訳を代入します。

中断管理: interruption-level および relevance-score

iOS 15 より、Apple はフォーカスモード (Focus Mode) を導入し、開発者が通知の中断レベルを指定する必要があります。interruption-level は、passive (音なし、画面起動なし)、active (標準動作)、time-sensitive (フォーカスを抜ける、特別な権限が必要)、critical (医療・緊急事態) の値を取ります。relevance-score (0–1) は、フォーカスシステムが同じカテゴリ内の通知をランク付けするのに役立ちます。

thread-id による通知グルーピング

thread-id キーは、ノーティフィケーションセンターで通知をグループ化します。同じ thread-id をもつすべての通知は、ユーザーが展開できる単一のグループとして表示されます。これは、メッセンジャーで同じ連絡先からのメッセージがまとめられる場合や、同じタイプの複数の通知を送信するアプリに特に便利です。

カスタムフィールドとデータ転送

カスタムフィールドは、aps ディクショナリの外部にあり、開発者がデバイスに追加データを送信するために追加するキーです。サーバーはそれらをペイロードのルート JSON オブジェクトに含め、アプリは UNNotificationContent の userInfo を通じて取得します。カスタムフィールドは aps とキー名が重複してはならず、解析中の競合を防ぎます。

カスタムデータの制限

主な制限は、ペイロードの総サイズが 4096 バイトを超えてはならないことです。カスタムフィールドは、必須の aps キーとこの制限を争うため、送信するデータのサイズを最小限にすることが重要です。ショートなキー名を使用し(例: “uid” は “user-id” の代わり)、大きな JSON 構造を避け、完全なデータオブジェクトの代わりに識別子のみを送信します。

カスタムフィールドのセキュリティと検証

カスタムフィールドは、サーバーから伝わり、検証なしで信頼してはなりません。常に検証してください解析時にカスタムフィールドの型と値を: オプショナルバインディングでキーの存在を確認し、as? String/Int/Dictionary で期待される型に変換し、値がない場合の処理を行います。ペイロードからのデータに対しては、force unwrap (!) を絶対に使用しないでください—サーバーが無効なデータを送信する可能性があり、アプリがクラッシュする可能性があります。

json
{
    "aps": {
        "alert": {
            "title": "新しいメッセージ",
            "body": "こんにちは! お元気ですか?"
        },
        "badge": 5,
        "sound": "default",
        "category": "message",
        "thread-id": "chat_4521",
        "mutable-content": 1
    },
    "sender-id": "user_789",
    "chat-id": "chat_4521",
    "message-type": "text",
    "image-url": "https://cdn.example.com/img.jpg"
}

カスタムフィールドの命名推奨

プロジェクト内のすべてのペイロードで、カスタムフィールドに一貫した命名スタイルを使用します。kebab-case (message-type) または camelCase (messageType) — どちらのアプローチも可能ですが、プロジェクト内での一貫性が重要です。長い名前を避けましょう: “uid” は “user-identifier” の代わり、“img” は “profile-image-url” の代わり。キー名の各文字が 4096 制限の 1 バイトを消費します。

異なるタイプの通知に対するペイロード例

異なるシナリオの push 通知では、ペイロードのキーの組み合わせが違います。いくつかのタイピカルな例を見てみましょう: シンプルなテキスト通知、ローカライズされた通知、サイレント push、メディア添付付きリッチ通知です。

シンプルなテキスト通知

テキストと音のベーシックなペイロード—ユーザーに通知を表示するための最小構成です。文字列としての alertは短いメッセージを提供し、sound default は標準のシステム音を再生します。Badge はオプションで、アプリアイコン上の数値を設定します。category と thread-id は、グルーピングとインタラクティビティのために追加されます。

json
{
    "aps": {
        "alert": "リマインダー: 15分後に会議",
        "badge": 3,
        "sound": "default"
    }
}

ローカライズされた通知

異なる言語のデバイスに通知を送信するには、ハードコードされたテキストの代わりに、ローカライゼーションキーを使用します。title-loc-keyは、アプリの Localizable.strings のキーを参照し、title-loc-args は引数を提供します。これにより、すべてのデバイスに 1 つのペイロードを送信でき、アプリが適切な言語でテキストを表示します。

json
{
    "aps": {
        "alert": {
            "title-loc-key": "NEW_MESSAGE_TITLE",
            "title-loc-args": ["アンナ"],
            "loc-key": "NEW_MESSAGE_BODY",
            "loc-args": ["こんにちは!"]
        },
        "sound": "message.caf"
    }
}

バックグラウンド同期のサイレント push

通知を表示せずにバックグラウンド同期を行うには、alert なしで content-available: 1 を使用します。カスタムフィールドは、処理のための操作タイプとデータを指定します。システムは、アプリをバックグラウンドで起動し、fetchCompletionHandler で didReceiveRemoteNotification をコールし、アプリが同期を実行します。

json
{
    "aps": {
        "content-available": 1
    },
    "sync-type": "invalidate-cache",
    "timestamp": "2026-07-03T12:00:00Z"
}

画像付きリッチ通知

メディア添付を表示するには、Service Extension を起動するための mutable-content: 1 と、カスタムフィールド内の画像 URL が必要です。mutable-content: 1 は、UNNotificationServiceExtension を起動するようにシステムに指示し、URL から画像をダウンロードし、UNNotificationAttachment として追加します。category キーは、アクションボタンを表示するための登録されたカテゴリを指定します。

json
{
    "aps": {
        "alert": {
            "title": "新商品",
            "body": "新コレクションをチェック"
        },
        "category": "product",
        "mutable-content": 1
    },
    "media-url": "https://cdn.example.com/product.jpg"
}

アプリでのペイロード処理とパーシング

UNNotificationContent.userInfoには、システム処理後の受信ペイロードの完全なディクショナリが含まれます。アプリは UNUserNotificationCenter のデリゲートで、通知受信時(フォアグラウンド)、通知タップ時、および Service Extension および Content Extension でペイロードにアクセスします。カスタムデータを抽出し、次のアクションを決定するためには、正しいパーシングが不可欠です。

通知タップ時の AppDelegate でのパーシング

ユーザーが通知をタップすると、システムは UNUserNotificationCenterDelegate の didReceive response メソッドをコールします。response.notification.request.content.userInfoには、完全なペイロードが含まれます。開発者はカスタムフィールドを抽出し、アクションのタイプ(例: チャットを開く、製品へナビゲートする)を決定し、アプリで適切なナビゲーションを起動します。

swift
func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
) {
    let userInfo = response.notification
        .request.content.userInfo

    guard let chatId = userInfo["chat-id"] as? String
    else {
        completionHandler()
        return
    }

    let messageType = userInfo["message-type"]
        as? String ?? "text"

    NavigationRouter.shared.navigate(
        to: .chat(chatId: chatId,
                  messageType: messageType))
    completionHandler()
}

Service Extension でのペイロード検証

Service Extension は、通知が表示される前にペイロードを受け取り、変更することができます。ペイロードの検証は didReceive での最初のステップです: 必須のカスタムフィールドを確認し、添付 URL を検証し、データ型を検証します。ペイロードが無効の場合は、不要な処理に時間をかけないように、即座に元のコンテンツでコンプリーションハンドラーをコールします。

ペイロードのログとモニタリング

プロダクションで push 通知をデバッグするには、構造化されたペイロードロギングを使用します。OSLogは、“notifications” カテゴリで debug レベルでペイロードをログできます。サーバー側では APNS 応答を監視します: 成功応答には、送信されたペイロードとの対応付けのための apns-id が含まれ、400 エラーは不正な JSON またはサイズ制限超過を示しています。

よくある質問

APNS ペイロードの最大サイズは?

最大ペイロードサイズは、一般的な push 通知の場合は 4096 バイト、VoIP push (PushKit) の場合は 5120 バイトです。この制限を超えると、APNS は 400 Bad Request エラーを返します。サイズは文字ではなくバイトで計算されます—UTF-8 エンコーディングを考慮してください。

複数の言語でローカライズされた通知を送信するには?

alert 内で loc-key、title-loc-key、loc-args、title-loc-args のキーを使用します。アプリは、デバイスの言語に基づいて、自分の Localizable.strings から翻訳を代入します。これにより、言語に関係なく、すべてのデバイスに単一のペイロードを送信できます。

content-available と mutable-content の違いは?

content-availableは、通知を表示せずに、データ処理(サイレント push)のためにアプリをバックグラウンドで起動します。mutable-contentは、表示前にコンテンツを変更する Service Extension を起動します。両方のキーを組み合わせて、バックグラウンド処理とその後の通知変更を行うことができます。

サーバーが正しいペイロードを送信したか確認するには?

テストには APNS Sandbox を使用し、Apple サーバーの HTTP 応答を確認します: 200 OK は配信成功を意味します。構造検証には、CI/CD パイプラインで JSON スキーマを使用します。Xcode では、xcrun simctl push を使用してシミュレーターでテスト通知を送信します。

Apple サーバー応答の apns-id とは?

apns-idは、APNS システムにおける固有の push 通知識別子で、配信成功後に応答で返されます。Logs API を通じて配信を追跡したり、デバッグに使用されます。サーバーは、送信された各通知に対して apns-id を保存する必要があります。

まとめ

  • Notification Payload — テキスト、音、バッジ、バックグラウンド処理を定義する必須の aps ディクショナリをもつ push 通知用の JSON 構造体。
  • サイズ制限 — APNS は 4096 バイト、VoIP は 5120 バイト。超過すると Apple サーバーから 400 Bad Request エラーが返されます。
  • aps ディクショナリには、alert、badge、sound、content-available、mutable-content、category、thread-id、interruption-level、relevance-score のキーが含まれます。
  • カスタムフィールドは aps の外部で送信され、userInfo から取得します。解析時は常に型と値を検証してください。
  • ローカライゼーションは、loc-key および title-loc-key を使用して実装され、翻訳を代入するためにアプリの Localizable.strings を参照します。
  • interruption-levelは、フォーカスモードでの通知動作を管理します: passive、active、time-sensitive、critical。
  • Notification Payloadは、push 通知システム全体の基礎です。デバイス上の各通知の配信、表示、処理の正確さはこれに依存しています。

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

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

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

こちらもお読みください