اعلان محلی پیامی است که برنامه بدون مشارکت سرور راه دور برای کاربر ارسال میکند. تمام دادهها مستقیماً روی دستگاه گیرنده پردازش و نمایش داده میشوند. چنین مکانیزمی برای یادآوریها، تایمرها و زنگهای بیدارباش وقتی برنامه در پسزمینه یا بسته است مناسب میباشد. طبق Apple Developer Documentation، UNUserNotificationCenter مدیریت متمرکز اعلانهای محلی در iOS را فراهم میکند.
نکات اصلی
اعلان محلی پیامی است که توسط سیستم عامل روی همان دستگاهی که برنامه نصب شده تولید و نمایش داده میشود. بر خلاف اعلانهای push، اعلانهای محلی از سرور خارجی عبور نمیکنند — تمام منطق برنامهریزی در سمت کلاینت انجام میشود.
چنین اعلانهایی بدون توجه به وضعیت برنامه کار میکنند: چه فعال باشد، چه کوچک شده یا کاملاً بسته باشد. سیستم عامل تحویل را در زمان تعیین شده بر عهده میگیرد و توسعهدهنده فقط محتوا و trigger را مشخص میکند.
سیستم تحویل اعلان محلی را حتی در صورت عدم وجود شبکه تضمین میکند. این مزیت کلیدی نسبت به اعلانهای push است که نیاز به اتصال پایدار اینترنت و سرور فعال دارند.
هر اعلان محلی از سه بخش تشکیل شده است: محتوا (عنوان، متن، صدا)، trigger (شرط زمانی یا جغرافیایی) و شناسه درخواست. شناسه امکان لغو یا بهروزرسانی اعلان را قبل از تحویل آن فراهم میکند.
توسعهدهنده میتواند تا 64 اعلان محلی برای یک برنامه در iOS و تعداد نامحدود در Android تنظیم کند. تفاوت به محدودیتهای معماری سیستمهای عامل مربوط میشود.
هر دو پلتفرم APIهای خود را برای کار با اعلانهای محلی ارائه میدهند. در iOS عنصر مرکزی UNUserNotificationCenter است، در Android — NotificationManager. با وجود رابطهای مختلف، منطق یکسان است: برنامه درخواستی ایجاد میکند، آن را در سیستم ثبت میکند و سیستم عامل اعلان را در زمان مشخص شده تحویل میدهد.
iOS برای رویدادهای تقویمی از UNCalendarNotificationTrigger، برای بازههای زمانی از UNTimeIntervalNotificationTrigger و برای موقعیت جغرافیایی از UNLocationNotificationTrigger استفاده میکند. Android AlarmManager، WorkManager و برنامهریزی دقیق از طریق setExact را ارائه میدهد.
از نسخه Android 12 — SCHEDULE_EXACT_ALARM نیاز به مجوز ویژه از کاربر دارد. در iOS مجوز یک بار از طریق UNUserNotificationCenter.requestAuthorization درخواست میشود و کاربر سطح دسترسی را انتخاب میکند: بنرها، صداها، نشانها.
اعلانهای محلی بر اساس نوع trigger طبقهبندی میشوند، نه بر اساس محتوا. هر نوع تعیین میکند که اعلان چه زمانی و تحت چه شرایطی به کاربر نشان داده شود.
در iOS و Android انواع triggerها متفاوت پیادهسازی شدهاند، اگرچه طبقهبندی منطقی یکسان است. iOS برای تاریخها از UNCalendarNotificationTrigger، برای بازهها از UNTimeIntervalNotificationTrigger و برای موقعیت جغرافیایی از UNLocationNotificationTrigger استفاده میکند. Android AlarmManager با setExact و setRepeating و همچنین WorkManager برای وظایف تأخیری را ارائه میدهد.
| نوع trigger | توضیحات | مثال |
|---|---|---|
| بازه زمانی | اعلان پس از N ثانیه از راهاندازی | تایمر شمارش معکوس |
| تاریخ تقویمی | اعلان در زمان و تاریخ مشخص | یادآوری جلسه |
| موقعیت جغرافیایی | اعلان هنگام ورود/خروج از منطقه | یادآوری نزدیک فروشگاه |
| بیقید | تحویل فوری هنگام فراخوانی API | اعلان دانلود |
در iOS همچنین UNNotificationAttachment در دسترس است — پیوست تصویر، صدا یا ویدئو در بدنه اعلان. Android از قالبهای سفارشی با دکمهها و تصاویر بزرگ از طریق NotificationCompat.Style پشتیبانی میکند.
انتخاب trigger به سناریو بستگی دارد: یادآوریهای تقویمی از طریق trigger تقویمی بهترین عملکرد را دارند و یادآوریهای جغرافیایی — از طریق موقعیت جغرافیایی. triggerهای بازهای برای رویدادهای منظم با دوره ثابت مناسب هستند.
در iOS اعلانهای محلی توسط سیستم حتی با برنامه بسته تحویل داده میشوند — UNUserNotificationCenter صف را مستقل مدیریت میکند. در Android تحویل به مکانیزم انتخاب شده بستگی دارد: AlarmManager حتی با صفحه خاموش فعال میشود و WorkManager با در نظر گرفتن صرفهجویی در انرژی.
اعلانهای محلی مسائلی را حل میکنند که زیرساخت خارجی اضافی یا غیرقابل دسترس است. سناریوهای اصلی: یادآوریها، تایمرها، نکات آموزشی و اقدامات به تأخیر افتاده.
تحقیقات Localytics نشان میدهد که برنامههای استفادهکننده از یادآوریهای محلی 35٪ کاربران بیشتری را در هفته اول پس از نصب حفظ میکنند. این اعلانهای محلی را به ابزاری قدرتمند برای آموزش اولیه تبدیل میکند.
مهم است که از فراوانی سوءاستفاده نکنید — سیستم خود اعلانهای یک برنامه را گروهبندی میکند و کاربر میتواند اگر آزاردهنده باشند همه اعلانهای محلی را خاموش کند. فراوانی بهینه بیش از 2–3 اعلان در روز برای رویدادهای غیر بحرانی نیست.
برای برنامهریزی اعلان محلی در Android از NotificationManager همراه با AlarmManager استفاده کنید. از Android 8+ ابتدا باید یک کانال اعلان ایجاد کنید، در غیر این صورت اعلان نمایش داده نخواهد شد.
val channelId = "reminder_channel"
val notificationId = "task_reminder_42"
val channel = NotificationChannel(
channelId,
"یادآوریها",
NotificationManager.IMPORTANCE_HIGH
).apply {
description = "کانال یادآوری وظایف"
}
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(channel)
val intent = Intent(this, ReminderReceiver::class.java).apply {
putExtra("notification_id", notificationId)
putExtra("channel_id", channelId)
}
val pendingIntent = PendingIntent.getBroadcast(
this, notificationId.hashCode(),
intent, PendingIntent.FLAG_UPDATE_CURRENT
)
val alarmManager = getSystemService(AlarmManager::class.java)
alarmManager.setExact(
AlarmManager.RTC_WAKEUP,
triggerTimeMillis,
pendingIntent
)
در Android 12+ قبل از فراخوانی setExact مجوز SCHEDULE_EXACT_ALARM را بررسی کنید. اگر مجوز داده نشده است — از setWindow استفاده کنید که تحویل را در یک پنجره زمانی تضمین میکند.
هنگام فعال شدن AlarmManager سیستم یک Intent پخشی ارسال میکند که توسط BroadcastReceiver دریافت میشود. در داخل آن باید از طریق NotificationManager یک اعلان ایجاد و نمایش داده شود. اطمینان حاصل کنید که PendingIntent از FLAG_UPDATE_CURRENT استفاده میکند، در غیر این صورت با تغییر دادهها اعلانهای قدیمی به استفاده از Intent منسوخ ادامه خواهند داد.
در iOS اعلانهای محلی از طریق UNUserNotificationCenter با استفاده از UNMutableNotificationContent و یکی از triggerها ایجاد میشوند. قبل از برنامهریزی باید از کاربر مجوز گرفت.
import UserNotifications
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
guard granted else { return }
}
let content = UNMutableNotificationContent()
content.title = "یادآوری وظیفه"
content.body = "فراموش نکنید گزارش را تا ساعت 18:00 تکمیل کنید"
content.sound = .default
content.userInfo = ["task_id": "42"]
let trigger = UNTimeIntervalNotificationTrigger(
timeInterval: 3600,
repeats: false
)
let request = UNNotificationRequest(
identifier: "task_reminder_42",
content: content,
trigger: trigger
)
center.add(request)
iOS تا 64 درخواست همزمان اعلان محلی را پشتیبانی میکند. اگر حد تجاوز شود — سیستم درخواستهای جدید را تا زمانی که درخواستهای فعال تحویل یا لغو شوند رد میکند. برای بررسی صف فعلی از getPendingNotificationRequests استفاده کنید.
وقتی کاربر با اعلان محلی iOS تعامل میکند، متد userNotificationCenter:didReceive response delegate UNUserNotificationCenterDelegate فراخوانی میشود. در این متد شناسه درخواست، actionIdentifier (کدام دکمه فشرده شده) و userInfo سفارشی در دسترس است. این امکان تشخیص باز کردن ساده اعلان از فشردن دکمه خاص را فراهم میکند.
برای اینکه اعلانهای محلی مفید باشند و کاربر را آزار ندهند، چند قانون کلیدی را رعایت کنید. اول: فراوانی را کنترل کنید — بیش از 2–3 اعلان در روز برای رویدادهای غیر بحرانی، در غیر این صورت کاربر همه اعلانهای برنامه را خاموش میکند.
دوم: به کاربر انتخاب بدهید. در رابط کاربری امکان خاموش کردن انواع خاصی از اعلانهای محلی را اضافه کنید. در Android برای این کار از NotificationChannel جداگانه با importance پایین استفاده کنید، در iOS — یک دسته جداگانه در تنظیمات برنامه.
سوم: ارتباط زمینهای — اعلان باید زمانی ظاهر شود که کاربر به آن نیاز دارد. triggerهای جغرافیایی برای یادآوری کارهای نزدیک خانه ایدهآل هستند، تقویمی — برای جلسات، بازهای — برای اقدامات منظم مانند نوشیدن آب یا حرکات کششی. انواع را بدون نیاز مخلوط نکنید.
چهارم: روی دستگاههای واقعی تست کنید. شبیهساز iOS همه سناریوهای تحویل اعلانهای محلی، به ویژه در پسزمینه را شبیهسازی نمیکند. در Android از adb shell dumpsys notification برای بررسی صف اعلانهای برنامهریزی شده و پارامترهای آنها استفاده کنید. پنجم: همیشه به کاربر امکان خاموش کردن اعلانها را از طریق رابط برنامه بدهید — این الزام UX و رهنمودهای App Store Review است.
سوالات متداول
اعلان محلی توسط دستگاه بدون مشارکت سرور برنامهریزی و تحویل داده میشود. اعلان push نیاز به سرویس خارجی (FCM, APNS) و اتصال اینترنت دارد. اعلانهای محلی آفلاین کار میکنند، push — فقط با دسترسی به شبکه.
iOS به 64 درخواست همزمان برنامهریزی شده محدود میکند. Android محدودیت دقیقی ندارد، اما بیش از 500 اعلان میتواند عملکرد سیستم را کاهش دهد و بر زمان تحویل تأثیر بگذارد.
بله، در iOS از removePendingNotificationRequests با شناسه درخواست استفاده کنید. در Android NotificationManager.cancel را فراخوانی کنید یا PendingIntent را از طریق AlarmManager لغو کنید. شناسه یکتا برای لغو الزامی است.
در iOS مجوز الزاماً از طریق requestAuthorization درخواست میشود. در Android 13+ (Tiramisu) نیز مجوز POST_NOTIFICATIONS مورد نیاز است. نسخههای قدیمیتر Android برای اعلانهای محلی نیاز به مجوز صریح ندارند.
در iOS UNNotificationAction ایجاد کرده و به UNNotificationCategory اضافه کنید. در Android از NotificationCompat.Builder.addAction با PendingIntent برای BroadcastReceiver استفاده کنید. هر دکمه یک عمل جداگانه در برنامه راهاندازی میکند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید