Question
Can you update the badge number using silent push notifications?
Answer
The short answer is no — this is an Apple limitation by design.
Understanding Silent Push Notifications
Silent push notifications are designed to trigger background tasks without alerting the user directly. They are used primarily to refresh content or update the app state quietly. However, their utility in updating the app icon badge is severely limited by Apple’s policies.
Why Silent Push Notifications can’t reliably update the badge
A silent push (content-available: 1, no alert) is a background notification. Apple explicitly tells developers not to rely on it for user-visible changes such as the badge, and all background work it triggers is scheduled at the system’s discretion.
Newer iOS versions add further restrictions: background actions initiated by silent pushes are evaluated by the Duet Activity Scheduler Daemon (DASD), which scores each request based on factors such as:
- current battery level;
- how frequently the app is used;
- time since the app was installed;
- current processor temperature.
Only if the score is high enough is the background task executed. So even when a silent push is delivered, the work behind it may be delayed or dropped entirely — which makes it unreliable for timely badge updates.
Recommended approaches
1. Let Pushwoosh manage the badge (preferred). Add a Notification Service Extension that subclasses PushwooshNotificationServiceExtension; Pushwoosh then handles badge counting, delivery events and attachments for you, and you can send absolute or relative badge values (5, +1, -1) with the push itself:
import PushwooshFramework
class NotificationService: PushwooshNotificationServiceExtension {}
See Setting up badges for the full setup.
2. If you must sync from your own backend, use the silent push only as a hint to fetch the authoritative count, then set the badge with the current API. Note that UIApplication.shared.applicationIconBadgeNumber is deprecated since iOS 17 — use UNUserNotificationCenter.setBadgeCount(_:) instead:
UNUserNotificationCenter.current().setBadgeCount(newBadgeCount) { error in
if let error { print("Failed to set badge: \(error)") }
}
For iOS 16 and earlier you still need the legacy call as a fallback:
if #available(iOS 17.0, *) {
UNUserNotificationCenter.current().setBadgeCount(newBadgeCount)
} else {
UIApplication.shared.applicationIconBadgeNumber = newBadgeCount
}
This way the badge is updated while the app is in use or recently active, without depending on the unreliable delivery of silent pushes.
See also: Setting up badges in the Pushwoosh documentation.
Comments
0 comments
Article is closed for comments.