Notification Payload — ساختار JSON است که سرور از طریق APNS به دستگاه iOS ارسال میکند و محتوای اعلان push و رفتار هنگام دریافت آن را تعیین میکند. پیلود شامل کلیدهای اجباری و اختیاری است که متن، صدا، badge، پیوستهای رسانهای و پردازش پسزمینه را کنترل میکنند. طبق Apple Developer Documentation, 2026، حداکثر اندازه پیلود برای اعلانهای معمولی 4096 بایت و برای VoIP push 5120 بایت است که محدودیتهای شدیدی بر میزان دادههای ارسالی اعمال میکند.
نکات اصلی
Notification Payload (پیلود اعلان) — یک شی JSON است که سرور برای تحویل به دستگاه iOS به APNS (Apple Push Notification Service) ارسال میکند. پیلود شامل تمام دادههای لازم برای سیستم جهت نمایش اعلان است: عنوان، متن، صدا، badge و فراداده برای پردازش پسزمینه. ساختار پیلود به شدت توسط اپل تنظیم شده و شامل کلیدهای اجباری برای پردازش صحیح توسط سیستم است.
وقتی سرور یک اعلان push را از طریق HTTP/2 API APNS ارسال میکند، درخواست شامل هدرهای احراز هویت و بدنه JSON — پیلود است. APNS اعتبار پیلود را بررسی میکند: اگر JSON نامعتبر باشد یا از حد اندازه تجاوز کند، سرور اپل خطای 400 Bad Request را برمیگرداند. پس از اعتبارسنجی، APNS پیلود را به دستگاه تحویل میدهد، جایی که سیستم iOS آن را تجزیه کرده و تعیین میکند چگونه اعلان را پردازش کند — نمایش بنر، اجرای وظیفه پسزمینه یا پخش صدا.
فرمت پیلود APNS از یک پیلود متنی ساده در iOS 2 به یک ساختار JSON چندجزئی در نسخههای مدرن تکامل یافته است. iOS 10 پشتیبانی از پیوستهای رسانهای را از طریق mutable-content به ارمغان آورد، iOS 12 گروهبندی اعلانها را از طریق thread-id اضافه کرد، و iOS 15 supports-live-activities را برای Live Activities معرفی کرد. امروزه پیلود میتواند بسته به رفتار مورد نیاز اعلان تا ۱۵ کلید مختلف داشته باشد.
شی ریشه پیلود شامل دیکشنری aps و فیلدهای سفارشی اختیاری در سطح بالایی است. دیکشنری aps تنها عنصر اجباری است، اما درون آن بسته به نوع اعلان ترکیبات مختلفی از کلیدها میتواند وجود داشته باشد: alert، badge، sound، content-available، mutable-content، interruption-level و غیره.
| کلید aps | نوع | هدف |
|---|---|---|
| alert | String یا Dictionary | متن اعلان یا شی با title، subtitle، body، محلیسازی |
| badge | Number | عدد روی آیکون برنامه؛ 0 badge را حذف میکند |
| sound | String | نام فایل صوتی یا default برای صدای سیستمی |
| content-available | Number (1) | پرچم فعالسازی پسزمینه؛ 1 = silent push |
| mutable-content | Number (1) | پرچم فعالسازی Service Extension برای تغییر محتوا |
| category | String | شناسه دسته برای دکمهها و Content Extension |
| thread-id | String | شناسه گروه برای گروهبندی اعلانها |
| interruption-level | String | سطح قطع: passive، active، time-sensitive، critical |
| relevance-score | Number (0–1) | اولویت اعلان برای سیستم رتبهبندی هوشمند |
کلید alert میتواند یک رشته ساده (که بدنه اعلان میشود) یا یک دیکشنری با فیلدهای title، subtitle، body باشد. فرمت دیکشنری امکان تنظیم عنوان و زیرعنوان را جدا از متن اصلی فراهم میکند. برای اعلانهای محلیسازی شده از کلیدهای title-loc-key، title-loc-args، loc-key، loc-args استفاده میشود که به Localizable.strings برنامه ارجاع میدهند. این امکان ارسال پیلود بدون متن به زبان خاص را فراهم میکند — برنامه ترجمه را جایگزین میکند.
از iOS 15 به بعد، اپل مکانیزم Focus Mode را اضافه کرد که از توسعهدهنده میخواهد سطح قطع اعلان را مشخص کند. interruption-level مقادیر زیر را میپذیرد: passive (بدون صدا، بدون بیدار کردن صفحه)، active (رفتار استاندارد)، time-sensitive (از focus عبور میکند، نیاز به مجوز ویژه دارد) و critical (موقعیتهای پزشکی/اضطراری). کلید relevance-score (0–1) به سیستم Focus کمک میکند اعلانها را در یک دسته رتبهبندی کند.
کلید thread-id اعلانها را در Notification Center در گروهها ترکیب میکند. همه اعلانها با thread-id یکسان به صورت یک گروه نمایش داده میشوند که کاربر میتواند آن را باز کند. این به ویژه برای پیامرسانها مفید است، جایی که پیامهای یک مخاطب با هم گروهبندی میشوند، یا برای برنامههایی که اعلانهای زیادی از یک نوع ارسال میکنند.
فیلدهای سفارشی — هر کلید خارج از دیکشنری aps است که توسعهدهنده برای انتقال دادههای اضافی به دستگاه اضافه میکند. سرور آنها را در شی JSON ریشه پیلود قرار میدهد و برنامه آنها را از طریق userInfo در UNNotificationContent دریافت میکند. فیلدهای سفارشی نباید نام کلیدهای aps را تکرار کنند تا از تداخل در هنگام تجزیه جلوگیری شود.
محدودیت اصلی — اندازه کل پیلود نباید از 4096 بایت تجاوز کند. فیلدهای سفارشی برای این حد با کلیدهای اجباری aps رقابت میکنند، بنابراین مهم است که اندازه دادههای ارسالی را به حداقل برسانید. از نامهای کوتاه برای کلیدها استفاده کنید (مثلاً «uid» به جای «user-id»)، از ساختارهای JSON بزرگ خودداری کنید و فقط شناسهها را ارسال کنید، نه اشیاء کامل داده.
فیلدهای سفارشی از سرور میآیند و بدون بررسی نباید به آنها اعتماد کرد. همیشه اعتبارسنجی کنید انواع و مقادیر فیلدهای سفارشی را در هنگام تجزیه: وجود کلید را از طریق optional binding بررسی کنید، به نوع مورد انتظار با as? String/Int/Dictionary تبدیل کنید و حالت عدم وجود مقدار را مدیریت کنید. هرگز از force unwrap (!) برای دادههای پیلود استفاده نکنید — سرور ممکن است داده نامعتبر ارسال کند و برنامه crash کند.
{
"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 است.
سناریوهای مختلف اعلانهای push به ترکیبات مختلفی از کلیدها در پیلود نیاز دارند. بیایید چند نمونه معمولی را بررسی کنیم: اعلان متنی ساده، اعلان با محلیسازی، Silent Push و Rich Notification با پیوست رسانهای.
پیلود پایه با متن و صدا — حداقل پیکربندی برای نمایش اعلان به کاربر. Alert به عنوان رشته پیام کوتاهی میدهد، sound default صدای سیستم استاندارد را پخش میکند. Badge اختیاری است و شمارنده را روی آیکون تنظیم میکند. category و thread-id برای گروهبندی و تعامل اضافه میشوند.
{
"aps": {
"alert": "یادآوری: جلسه ۱۵ دقیقه دیگر",
"badge": 3,
"sound": "default"
}
}
برای ارسال به دستگاههایی با زبانهای مختلف به جای متن ثابت از کلیدهای محلیسازی استفاده کنید. title-loc-key به کلیدی در Localizable.strings برنامه ارجاع میدهد و title-loc-args آرگومانها را جایگزین میکند. این امکان ارسال یک پیلود به همه دستگاهها را فراهم میکند و برنامه خود متن را به زبان مناسب نمایش میدهد.
{
"aps": {
"alert": {
"title-loc-key": "NEW_MESSAGE_TITLE",
"title-loc-args": ["آنا"],
"loc-key": "NEW_MESSAGE_BODY",
"loc-args": ["سلام!"]
},
"sound": "message.caf"
}
}
برای همگامسازی پسزمینه بدون نمایش اعلان از content-available: 1 و عدم وجود alert استفاده میشود. فیلدهای سفارشی نوع عملیات و دادههای پردازش را مشخص میکنند. سیستم برنامه را در پسزمینه فعال میکند، didReceiveRemoteNotification را با fetchCompletionHandler فراخوانی میکند و برنامه همگامسازی را انجام میدهد.
{
"aps": {
"content-available": 1
},
"sync-type": "invalidate-cache",
"timestamp": "2026-07-03T12:00:00Z"
}
برای نمایش پیوست رسانهای، mutable-content: 1 برای فعالسازی Service Extension و URL تصویر در فیلد سفارشی لازم است. mutable-content: 1 به سیستم علامت میدهد UNNotificationServiceExtension را راهاندازی کند که تصویر را از URL دانلود کرده و به عنوان UNNotificationAttachment اضافه میکند. category به دسته ثبتشده برای نمایش دکمههای اقدام اشاره میکند.
{
"aps": {
"alert": {
"title": "محصول جدید",
"body": "مجموعه جدید را ببینید"
},
"category": "product",
"mutable-content": 1
},
"media-url": "https://cdn.example.com/product.jpg"
}
UNNotificationContent.userInfo شامل دیکشنری کامل پیلود دریافتشده پس از پردازش توسط سیستم است. برنامه در delegate UNUserNotificationCenter هنگام دریافت اعلان (در پیشزمینه)، هنگام کلیک روی اعلان، و همچنین در Service Extension و Content Extension به پیلود دسترسی دارد. تجزیه صحیح برای استخراج دادههای سفارشی و تعیین اقدامات بعدی ضروری است.
وقتی کاربر روی اعلان کلیک میکند، سیستم متد didReceive response را در UNUserNotificationCenterDelegate فراخوانی میکند. در response.notification.request.content.userInfo پیلود کامل موجود است. توسعهدهنده فیلدهای سفارشی را استخراج میکند، نوع اقدام را تعیین میکند (مثلاً باز کردن چت، رفتن به محصول) و ناوبری مربوطه را در برنامه فراخوانی میکند.
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 پیلود را قبل از نمایش اعلان دریافت میکند و میتواند آن را تغییر دهد. اعتبارسنجی پیلود — اولین گام در didReceive: وجود فیلدهای سفارشی اجباری، صحت URL برای پیوستها و نوع داده را بررسی کنید. اگر پیلود نامعتبر است، فوراً completion handler را با محتوای اصلی فراخوانی کنید، بدون اتلاف وقت برای پردازش بیفایده.
برای اشکالزدایی اعلانهای push در تولید از ثبت ساختاریافته پیلودها استفاده کنید. OSLog امکان ثبت پیلود با دسته «notifications» و سطح debug را فراهم میکند. در سمت سرور، پاسخهای APNS را ردیابی کنید: پاسخ موفق شامل apns-id برای تطبیق با پیلود ارسالی است و خطای 400 نشاندهنده JSON نامعتبر یا تجاوز از اندازه است.
سوالات متداول
حداکثر اندازه پیلود — 4096 بایت برای اعلانهای push معمولی و 5120 بایت برای VoIP push (PushKit). در صورت تجاوز، APNS خطای 400 Bad Request برمیگرداند. اندازه بر حسب بایت محاسبه میشود، نه کاراکتر — رمزگذاری UTF-8 را در نظر بگیرید.
از کلیدهای loc-key، title-loc-key، loc-args و title-loc-args درون alert استفاده کنید. برنامه ترجمه را از Localizable.strings خود بر اساس زبان دستگاه جایگزین میکند. این امکان ارسال یک پیلود به همه دستگاهها را بدون توجه به زبان آنها فراهم میکند.
content-available برنامه را در پسزمینه برای پردازش داده بدون نمایش اعلان فعال میکند (silent push). mutable-content Service Extension را برای تغییر محتوا قبل از نمایش فعال میکند. هر دو کلید میتوانند با هم برای پردازش پسزمینه و تغییر بعدی اعلان استفاده شوند.
برای آزمایش از APNS Sandbox استفاده کنید و پاسخ HTTP سرور اپل را بررسی کنید: 200 OK به معنی ارسال موفق است. برای اعتبارسنجی ساختار از طرحهای JSON در pipeline CI/CD استفاده کنید. در Xcode اعلانهای آزمایشی را از طریق شبیهساز با دستور xcrun simctl push ارسال کنید.
apns-id — شناسه یکتای اعلان push در سیستم APNS که در پاسخ به ارسال موفق برگردانده میشود. برای ردیابی تحویل از طریق Logs API و اشکالزدایی استفاده میشود. سرور باید apns-id را برای هر اعلان ارسالی ذخیره کند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید