Local notifications in mobile development: essence, types, and how they work

Author: IT Sectr Published: 2026-03-19 Reading time: 8 min

A local notification is a message that the app sends to the user without involving a remote server. All data is processed and displayed directly on the recipient’s device. This mechanism is suitable for reminders, timers, and alarms when the app is in the background or closed. According to Apple Developer Documentation, UNUserNotificationCenter provides centralized management of local notifications on iOS.

Key Takeaways

  • Local notification — a message that is scheduled and delivered by the device without server involvement
  • Platforms — Android uses NotificationManager, iOS uses UNUserNotificationCenter
  • Scheduling — notifications can be triggered by time, geolocation, or calendar
  • Limitations — local notifications do not work across devices and require separate synchronization logic
  • UX — properly configured notifications increase engagement and bring users back to the app

What is a Local Notification?

A local notification is a trigger message that is generated and displayed by the operating system on the same device where the app is installed. Unlike push notifications, local notifications do not go through an external server — all scheduling logic runs on the client.

Such notifications work regardless of the app’s state: active, minimized, or completely closed. The operating system handles delivery at the scheduled time, while the developer only specifies the content and trigger.

The system guarantees delivery of local notifications even without network access. This is a key advantage over push notifications, which require a stable internet connection and a working server.

Main Request Components

Each local notification consists of three parts: content (title, body, sound), trigger (time or geo condition), and request identifier. The identifier allows canceling or updating the notification before delivery.

A developer can schedule up to 64 local notifications per app on iOS and an unlimited number on Android. This difference is due to architectural constraints of the operating systems.

How Do Local Notifications Work on iOS and Android?

Both platforms provide their own APIs for working with local notifications. On iOS, the central component is UNUserNotificationCenter, on Android — NotificationManager. Despite different interfaces, the logic is the same: the app creates a request, registers it with the system, and the OS delivers the notification at the scheduled time.

iOS uses UNCalendarNotificationTrigger for calendar events, UNTimeIntervalNotificationTrigger for intervals, and UNLocationNotificationTrigger for geolocation. Android offers AlarmManager, WorkManager, and precise scheduling via setExact.

Since Android 12 — SCHEDULE_EXACT_ALARM requires special permission from the user. On iOS, permission is requested once through UNUserNotificationCenter.requestAuthorization, and the user chooses access level: banners, sounds, badges.

Types of Local Notifications

Local notifications are classified by trigger type, not by content. Each type determines when and under what conditions the notification will be shown to the user.

Trigger Comparison by Platform

On iOS and Android, trigger types are implemented differently, although the logical classification is the same. iOS uses UNCalendarNotificationTrigger for dates, UNTimeIntervalNotificationTrigger for intervals, and UNLocationNotificationTrigger for geolocation. Android offers AlarmManager with setExact and setRepeating, as well as WorkManager for deferred tasks.

Trigger TypeDescriptionExample
Time IntervalNotification N seconds after launchCountdown timer
Calendar DateNotification at a specific time and dateMeeting reminder
GeolocationNotification on entering/leaving a regionStore reminder
ImmediateInstant delivery upon API callDownload notification

iOS also supports UNNotificationAttachment — attaching an image, audio, or video to the notification body. Android supports custom templates with buttons and large images via NotificationCompat.Style.

The choice of trigger depends on the scenario: calendar reminders work best with calendar triggers, geo reminders with geolocation. Interval triggers are suitable for recurring events with a fixed period.

Trigger Behavior in Background

On iOS, local notifications are delivered by the system even when the app is closed — UNUserNotificationCenter manages the queue independently. On Android, delivery depends on the chosen mechanism: AlarmManager fires even with the screen off, while WorkManager accounts for power saving.

Use Cases in Mobile Apps

Local notifications solve tasks where external infrastructure is excessive or unavailable. Main scenarios: reminders, timers, onboarding tips, and deferred actions.

  • Reminders — a calendar app creates a local notification for the specified event date
  • Onboarding tips — a day after installation, the app shows a screen tip
  • Timers — a kitchen timer fires after a set time even with the app closed
  • Operation progress — notification about completed download or data export

Research by Localytics shows that apps using local reminders retain 35% more users in the first week after installation. This makes local notifications a powerful onboarding tool.

It is important not to overuse frequency — the system groups notifications from the same app, and the user can disable all local notifications if they become annoying. Optimal frequency is no more than 2–3 notifications per day for non-critical events.

Scheduling Example on Android

To schedule a local notification on Android, use NotificationManager together with AlarmManager. On Android 8+, you must first create a notification channel, otherwise the notification will not be displayed.

kotlin
val channelId = "reminder_channel"
val notificationId = "task_reminder_42"

val channel = NotificationChannel(
    channelId,
    "Reminders",
    NotificationManager.IMPORTANCE_HIGH
).apply {
    description = "Channel for task reminders"
}

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
)

On Android 12+, check the SCHEDULE_EXACT_ALARM permission before calling setExact. If permission is not granted — use setWindow, which guarantees delivery within a time window.

Handling in BroadcastReceiver

When AlarmManager fires, the system sends a broadcast Intent that is received by BroadcastReceiver. Inside it, you need to create and show the notification via NotificationManager. Make sure that PendingIntent uses FLAG_UPDATE_CURRENT, otherwise old notifications will continue using outdated Intent when data changes.

Scheduling Example on iOS

On iOS, local notifications are created via UNUserNotificationCenter using UNMutableNotificationContent and one of the triggers. Before scheduling, you must request permission from the user.

swift
import UserNotifications

let center = UNUserNotificationCenter.current()

center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
    guard granted else { return }
}

let content = UNMutableNotificationContent()
content.title = "Task reminder"
content.body = "Don’t forget to complete the report by 6:00 PM"
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 supports up to 64 concurrent local notification requests. If the limit is exceeded, the system rejects new requests until active ones are delivered or canceled. Use getPendingNotificationRequests to check the current queue.

Delegate Response Handling

When a user interacts with a local notification on iOS, the userNotificationCenter:didReceive response method of the UNUserNotificationCenterDelegate is called. This method provides the request identifier, actionIdentifier (which button was pressed), and custom userInfo. This allows distinguishing between a simple notification open and pressing a specific action button.

Best Practices for Local Notifications

To make local notifications useful rather than annoying, follow several key rules. First: control frequency — no more than 2–3 notifications per day for non-critical events, otherwise the user will disable all app notifications.

Second: give the user choice. Add the ability in the interface to disable certain types of local notifications. On Android, use a separate NotificationChannel with low importance for this; on iOS, use a separate category in the app settings.

Third: contextual relevance — the notification should appear when the user needs it. Geo triggers are ideal for reminders near home, calendar triggers for meetings, interval triggers for regular activities like drinking water or stretching. Do not mix types unnecessarily.

Fourth: test on real devices. The iOS simulator does not emulate all local notification delivery scenarios, especially in the background. On Android, use adb shell dumpsys notification to check the queue of scheduled notifications and their parameters. Fifth: always provide the user with the ability to disable notifications through the app interface — this is a mandatory UX and App Store Review Guidelines requirement.

Frequently Asked Questions

What is the difference between a local notification and a push notification?

A local notification is scheduled and delivered by the device without server involvement. A push notification requires an external service (FCM, APNS) and an internet connection. Local notifications work offline, push only work with network access.

How many local notifications can be scheduled?

iOS limits to 64 concurrently scheduled requests. Android does not have a strict limit, but over 500 notifications may reduce system performance and affect delivery time.

Can a local notification be canceled after scheduling?

Yes, on iOS use removePendingNotificationRequests with the request identifier. On Android, call NotificationManager.cancel or cancel the PendingIntent via AlarmManager. A unique identifier is mandatory for cancellation.

Is user permission required for local notifications?

On iOS, permission is mandatory via requestAuthorization. On Android 13+ (Tiramisu), the POST_NOTIFICATIONS permission is also required. Older Android versions do not require explicit permission for local notifications.

How to add buttons to a local notification?

On iOS, create UNNotificationAction and add it to UNNotificationCategory. On Android, use NotificationCompat.Builder.addAction with a PendingIntent targeting BroadcastReceiver. Each button triggers a separate action in the app.

Summary

  • Local notifications — messages that are scheduled and delivered by the device without server infrastructure
  • UNUserNotificationCenter — the main API for local notifications on iOS
  • NotificationManager — the main API for local notifications on Android
  • Trigger types — time interval, calendar date, geolocation, and immediate delivery
  • Limits — iOS limits to 64 scheduled requests, Android has no strict limit
  • Permissions — iOS and Android 13+ require explicit user consent for notifications
  • Offline — local notifications work without an internet connection, making them more reliable than push

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also