Notification Payload — khái niệm, cấu trúc JSON và phân tích

Tác giả: IT Sectr Đã đăng: 2026-03-20 Thời gian đọc: 10 phút

Notification Payload là một cấu trúc JSON mà máy chủ gửi qua APNS đến thiết bị iOS, xác định nội dung của thông báo push và hành vi khi nhận được nó. Payload bao gồm các key bắt buộc và tùy chọn kiểm soát văn bản, âm thanh, huy hiệu, tập tin đính kèm phương tiện và xử lý nền. Theo Apple Developer Documentation, 2026, kích thước payload tối đa là 4096 byte cho thông báo thông thường và 5120 byte cho VoIP push, áp đặt giới hạn nghiêm ngặt về lượng dữ liệu truyền tải.

Điểm Chính

  • Cấu trúc aps — một từ điển bắt buộc với các key alert, badge, sound và content-available xác định hành vi trực quan và âm thanh của thông báo.
  • Giới hạn kích thước — kích thước payload tối đa là 4096 byte cho APNS và 5120 byte cho VoIP push; bất cứ thứ gì lớn hơn đều bị máy chủ Apple từ chối.
  • Trường tùy chỉnh — bất kỳ dữ liệu bổ sung nào được truyền ở cùng cấp với aps và có sẵn trong userInfo sau khi nhận thông báo.
  • Bản địa hóa alert — các key title-loc-key, loc-key và loc-args cho phép hiển thị văn bản đã địa phương hóa mà không cần gửi các payload khác nhau cho từng ngôn ngữ.
  • Request-identifier — một định danh tùy chỉnh trong phản hồi APNS để theo dõi trạng thái giao hàng và lệnh gọi lại từ máy chủ Apple.

Notification Payload là gì

Notification Payload là một đối tượng JSON mà máy chủ gửi đến APNS (Apple Push Notification Service) để chuyển đến thiết bị iOS. Payload chứa tất cả dữ liệu hệ thống cần để hiển thị thông báo: tiêu đề, văn bản, âm thanh, huy hiệu và siêu dữ liệu cho xử lý nền. Cấu trúc payload được Apple quy định nghiêm ngặt và bao gồm các key bắt buộc để hệ thống xử lý chính xác.

Vai trò của Payload trong việc gửi push

Khi máy chủ gửi thông báo push qua APNS HTTP/2 API, yêu cầu chứa header ủy quyền và phần thân JSON — payload. APNS xác thực payload: nếu JSON không hợp lệ hoặc vượt quá giới hạn kích thước, máy chủ Apple trả về lỗi 400 Bad Request. Sau khi xác thực, APNS chuyển payload đến thiết bị, nơi iOS phân tích nó và xác định cách xử lý thông báo — hiển thị banner, chạy tác vụ nền hoặc phát âm thanh.

Sự phát triển của định dạng Payload

Định dạng payload APNS đã phát triển từ một payload văn bản đơn giản trong iOS 2 thành cấu trúc JSON nhiều thành phần trong các phiên bản hiện đại. iOS 10 đã giới thiệu hỗ trợ tập tin đính kèm phương tiện qua mutable-content, iOS 12 thêm tính năng nhóm thông báo qua thread-id, và iOS 15 giới thiệu supports-live-activities cho Live Activities. Ngày nay, một payload có thể chứa tới 15 key khác nhau tùy thuộc vào hành vi thông báo mong muốn.

Cấu trúc Payload APNS: Key bắt buộc và tùy chọn

Đối tượng gốc của payload chứa một từ điển aps và các trường tùy chỉnh tùy chọn ở cấp cao nhất. Từ điển aps là phần tử bắt buộc duy nhất, nhưng bên trong nó có thể xuất hiện nhiều tổ hợp key khác nhau tùy thuộc vào loại thông báo: alert, badge, sound, content-available, mutable-content, interruption-level và các key khác.

Key apsLoạiMục đích
alertString hoặc DictionaryVăn bản thông báo hoặc đối tượng có title, subtitle, body và bản địa hóa
badgeNumberSố trên biểu tượng ứng dụng; 0 xóa huy hiệu
soundStringTên tệp âm thanh hoặc default cho âm thanh hệ thống
content-availableNumber (1)Cờ kích hoạt nền; 1 = push ẩn
mutable-contentNumber (1)Cờ kích hoạt Service Extension để sửa đổi nội dung
categoryStringĐịnh danh danh mục cho nút và Content Extension
thread-idStringĐịnh danh nhóm để nhóm thông báo
interruption-levelStringMức độ gián đoạn: passive, active, time-sensitive, critical
relevance-scoreNumber (0–1)Ưu tiên thông báo cho hệ thống xếp hạng thông minh

Key alert: Định dạng String và Dictionary

Key alert có thể là một chuỗi đơn giản (trở thành nội dung thông báo) hoặc một từ điển với các trường title, subtitle, body. Định dạng từ điển cho phép đặt tiêu đề và phụ đề riêng biệt với văn bản chính. Đối với thông báo đã địa phương hóa, các key title-loc-key, title-loc-args, loc-key và loc-args được sử dụng, tham chiếu đến Localizable.strings của ứng dụng. Điều này cho phép gửi một payload mà không có văn bản ngôn ngữ cụ thể — ứng dụng thay thế bản dịch.

Quản lý gián đoạn: interruption-level và relevance-score

Bắt đầu từ iOS 15, Apple đã giới thiệu cơ chế Focus Mode, yêu cầu nhà phát triển chỉ định mức độ gián đoạn của thông báo. interruption-level chấp nhận các giá trị: passive (không âm thanh, không đánh thức màn hình), active (hành vi tiêu chuẩn), time-sensitive (xuyên qua Focus, yêu cầu ủy quyền đặc biệt) và critical (tình huống y tế/khẩn cấp). Key relevance-score (0–1) giúp hệ thống Focus xếp hạng các thông báo trong cùng một danh mục.

Nhóm thông báo qua thread-id

Key thread-id nhóm các thông báo trong Trung tâm thông báo. Tất cả thông báo có cùng thread-id được hiển thị dưới dạng một nhóm duy nhất mà người dùng có thể mở rộng. Điều này đặc biệt hữu ích cho trình nhắn tin, nơi tin nhắn từ cùng một liên hệ được nhóm lại, hoặc cho các ứng dụng gửi nhiều thông báo cùng loại.

Trường tùy chỉnh và truyền dữ liệu

Trường tùy chỉnh là bất kỳ key nào bên ngoài từ điển aps mà nhà phát triển thêm vào để truyền dữ liệu bổ sung đến thiết bị. Máy chủ bao gồm chúng trong đối tượng JSON gốc của payload, và ứng dụng truy xuất chúng qua userInfo trong UNNotificationContent. Các trường tùy chỉnh không được trùng tên key với aps để tránh xung đột khi phân tích.

Giới hạn đối với dữ liệu tùy chỉnh

Giới hạn chính là tổng kích thước payload không được vượt quá 4096 byte. Các trường tùy chỉnh cạnh tranh giới hạn này với các key bắt buộc của aps, vì vậy điều quan trọng là giảm thiểu kích thước dữ liệu truyền. Sử dụng tên key ngắn (ví dụ: “uid” thay vì “user-id”), tránh cấu trúc JSON lớn và chỉ truyền định danh thay vì toàn bộ đối tượng dữ liệu.

Bảo mật và xác thực trường tùy chỉnh

Trường tùy chỉnh đến từ máy chủ và không nên được tin cậy mà không xác thực. Luôn xác thực loại và giá trị của trường tùy chỉnh khi phân tích: kiểm tra sự tồn tại của key thông qua liên kết tùy chọn, chuyển đổi sang loại mong đợi bằng as? String/Int/Dictionary và xử lý trường hợp không có giá trị. Đừng bao giờ sử dụng force unwrap (!) cho dữ liệu từ payload — máy chủ có thể gửi dữ liệu không hợp lệ, khiến ứng dụng bị treo.

json
{
    "aps": {
        "alert": {
            "title": "Tin nhắn mới",
            "body": "Xin chào! Bạn có khỏe không?"
        },
        "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"
}

Đề xuất đặt tên trường tùy chỉnh

Sử dụng kiểu đặt tên nhất quán cho các trường tùy chỉnh trong tất cả các payload của dự án. kebab-case (message-type) hoặc camelCase (messageType) — cả hai phương pháp đều chấp nhận được, nhưng tính nhất quán trong dự án là quan trọng. Tránh tên dài: “uid” thay vì “user-identifier”, “img” thay vì “profile-image-url”. Mỗi ký tự trong tên key tiêu thụ một byte trong giới hạn 4096.

Ví dụ Payload cho các loại thông báo khác nhau

Các kịch bản khác nhau của thông báo push yêu cầu các tổ hợp key khác nhau trong payload. Hãy xem một số ví dụ điển hình: thông báo văn bản đơn giản, thông báo đã địa phương hóa, Silent Push và Thông báo Rich với tập tin đính kèm phương tiện.

Thông báo văn bản đơn giản

Một payload cơ bản với văn bản và âm thanh — cấu hình tối thiểu để hiển thị thông báo cho người dùng. Alert dưới dạng chuỗi cung cấp một thông điệp ngắn, sound default phát âm thanh hệ thống tiêu chuẩn. Badge là tùy chọn và đặt số trên biểu tượng ứng dụng. category và thread-id được thêm vào để nhóm và tương tác.

json
{
    "aps": {
        "alert": "Nhắc nhở: cuộc họp trong 15 phút",
        "badge": 3,
        "sound": "default"
    }
}

Thông báo đã địa phương hóa

Để gửi thông báo đến các thiết bị có ngôn ngữ khác nhau, hãy sử dụng các key bản địa hóa thay vì văn bản cứng. title-loc-key tham chiếu đến một key trong Localizable.strings của ứng dụng, và title-loc-args cung cấp đối số. Điều này cho phép gửi một payload duy nhất đến tất cả các thiết bị và ứng dụng hiển thị văn bản bằng ngôn ngữ thích hợp.

json
{
    "aps": {
        "alert": {
            "title-loc-key": "NEW_MESSAGE_TITLE",
            "title-loc-args": ["Anna"],
            "loc-key": "NEW_MESSAGE_BODY",
            "loc-args": ["Xin chào!"]
        },
        "sound": "message.caf"
    }
}

Silent Push với đồng bộ nền

Để đồng bộ nền mà không hiển thị thông báo, hãy sử dụng content-available: 1 mà không có alert. Các trường tùy chỉnh chỉ định loại hoạt động và dữ liệu để xử lý. Hệ thống kích hoạt ứng dụng trong nền, gọi didReceiveRemoteNotification với fetchCompletionHandler, và ứng dụng thực hiện đồng bộ.

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

Thông báo Rich có hình ảnh

Để hiển thị tập tin đính kèm phương tiện, cần có mutable-content: 1 để kích hoạt Service Extension, cùng với URL hình ảnh trong trường tùy chỉnh. mutable-content: 1 báo hiệu hệ thống khởi chạy UNNotificationServiceExtension, tải hình ảnh từ URL và thêm nó dưới dạng UNNotificationAttachment. Key category chỉ định một danh mục đã đăng ký để hiển thị các nút hành động.

json
{
    "aps": {
        "alert": {
            "title": "Sản phẩm mới",
            "body": "Xem bộ sưu tập mới"
        },
        "category": "product",
        "mutable-content": 1
    },
    "media-url": "https://cdn.example.com/product.jpg"
}

Xử lý và phân tích Payload trong ứng dụng

UNNotificationContent.userInfo chứa từ điển đầy đủ của payload đã nhận sau khi hệ thống xử lý. Ứng dụng truy cập payload trong ủy quyền UNUserNotificationCenter khi nhận thông báo (ở tiền cảnh), khi chạm vào thông báo, cũng như trong Service Extension và Content Extension. Việc phân tích chính xác là cần thiết để trích xuất dữ liệu tùy chỉnh và xác định các hành động tiếp theo.

Phân tích trong AppDelegate khi chạm vào thông báo

Khi người dùng chạm vào thông báo, hệ thống gọi phương thức didReceive response trong UNUserNotificationCenterDelegate. response.notification.request.content.userInfo chứa payload đầy đủ. Nhà phát triển trích xuất các trường tùy chỉnh, xác định loại hành động (ví dụ: mở trò chuyện, điều hướng đến sản phẩm) và kích hoạt điều hướng tương ứng trong ứng dụng.

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()
}

Xác thực Payload trong Service Extension

Service Extension nhận payload trước khi thông báo được hiển thị và có thể sửa đổi nó. Xác thực payload là bước đầu tiên trong didReceive: kiểm tra các trường tùy chỉnh bắt buộc, xác thực URL tập tin đính kèm và kiểm tra loại dữ liệu. Nếu payload không hợp lệ, hãy gọi completion handler với nội dung gốc ngay lập tức để tránh lãng phí thời gian vào xử lý không cần thiết.

Ghi nhật ký và giám sát Payload

Để gỡ lỗi thông báo push trong sản xuất, hãy sử dụng ghi nhật ký payload có cấu trúc. OSLog cho phép ghi nhật ký payload với danh mục “notifications” ở mức debug. Về phía máy chủ, hãy giám sát các phản hồi APNS: phản hồi thành công chứa apns-id để khớp với payload đã gửi, trong khi lỗi 400 cho biết JSON không hợp lệ hoặc vượt quá kích thước.

Câu hỏi thường gặp

Kích thước tối đa của payload APNS là bao nhiêu?

Kích thước tối đa của payload là 4096 byte cho thông báo push thông thường và 5120 byte cho VoIP push (PushKit). Vượt quá giới hạn này sẽ khiến APNS trả về lỗi 400 Bad Request. Kích thước được tính bằng byte, không phải ký tự — hãy tính đến mã hóa UTF-8.

Làm thế nào để gửi thông báo đã địa phương hóa bằng nhiều ngôn ngữ?

Sử dụng các key loc-key, title-loc-key, loc-args và title-loc-args trong alert. Ứng dụng thay thế bản dịch từ Localizable.strings dựa trên ngôn ngữ thiết bị. Điều này cho phép gửi một payload duy nhất đến tất cả các thiết bị bất kể ngôn ngữ của chúng.

Sự khác biệt giữa content-available và mutable-content là gì?

content-available kích hoạt ứng dụng trong nền để xử lý dữ liệu (silent push) mà không hiển thị thông báo. mutable-content kích hoạt Service Extension để sửa đổi nội dung trước khi hiển thị. Cả hai key có thể được sử dụng cùng nhau để xử lý nền và sửa đổi thông báo sau đó.

Làm thế nào để xác minh máy chủ đã gửi payload chính xác?

Sử dụng APNS Sandbox để kiểm tra và xác minh phản hồi HTTP của máy chủ Apple: 200 OK có nghĩa là gửi thành công. Để xác thực cấu trúc, hãy sử dụng lược đồ JSON trong đường ống CI/CD. Trong Xcode, gửi thông báo thử nghiệm qua trình mô phỏng bằng xcrun simctl push.

apns-id trong phản hồi của máy chủ Apple là gì?

apns-id là một định danh thông báo push duy nhất trong hệ thống APNS, được trả về trong phản hồi khi gửi thành công. Nó được sử dụng để theo dõi việc gửi qua API Logs và để gỡ lỗi. Máy chủ nên lưu trữ apns-id cho mỗi thông báo đã gửi.

Tổng kết

  • Notification Payload — cấu trúc JSON cho thông báo push với từ điển aps bắt buộc xác định văn bản, âm thanh, huy hiệu và xử lý nền.
  • Giới hạn kích thước — 4096 byte cho APNS, 5120 byte cho VoIP; vượt quá sẽ trả về lỗi 400 Bad Request từ máy chủ Apple.
  • Từ điển aps bao gồm các key alert, badge, sound, content-available, mutable-content, category, thread-id, interruption-level và relevance-score.
  • Trường tùy chỉnh được truyền bên ngoài aps và trích xuất qua userInfo; luôn xác thực loại và giá trị khi phân tích.
  • Bản địa hóa được thực hiện qua loc-key và title-loc-key, tham chiếu đến Localizable.strings của ứng dụng để thay thế bản dịch.
  • interruption-level quản lý hành vi thông báo trong chế độ Focus: passive, active, time-sensitive hoặc critical.
  • Notification Payload là nền tảng của toàn bộ hệ thống thông báo push; tính đúng đắn của việc gửi, hiển thị và xử lý mỗi thông báo trên thiết bị phụ thuộc vào nó.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm