didReceiveRemoteNotification not called, iOS 10
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
On iOS 10, didReceiveRemoteNotification is not the callback for every push-notification scenario. Which method runs depends on whether the notification is visible or silent, whether the app is in the foreground or background, and whether the event is being handled through UNUserNotificationCenterDelegate instead.
Start with the iOS 10 Notification Model
iOS 10 moved notification handling into the UserNotifications framework. That means debugging begins with the modern setup:
If authorization is missing or remote-notification registration never succeeds, none of the later callbacks will behave the way you expect.
The Callback Depends on the Scenario
This is the main source of confusion. On iOS 10, different notification scenarios use different callbacks:
- foreground visible notification:
userNotificationCenter(_:willPresent:withCompletionHandler:) - user taps a delivered notification:
userNotificationCenter(_:didReceive:withCompletionHandler:) - silent background notification:
application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
So if you are testing a visible alert while the app is open, didReceiveRemoteNotification may not be the method you see.
Foreground Notifications Use the Notification Center Delegate
If the app is open when a visible notification arrives, implement:
This is the correct place to observe or customize foreground presentation on iOS 10 and later.
If the user taps a delivered notification, use:
Silent Push Uses the Fetch Variant
If your app is supposed to wake in the background and do work without showing an alert, the relevant method is the fetch variant:
For this to work reliably, the notification payload typically needs:
And the app must have the Remote notifications background capability enabled.
App State Changes the Observed Behavior
You should test notification delivery by specific app state, not as one generic feature:
- app in foreground
- app in background
- app launched from a tapped notification
- app receiving a silent push
Those are related but different flows. If you only say "push is not calling my method," you may be watching the wrong method for the state you are actually testing.
Registration and APNs Delivery Still Matter
Before blaming the callback, confirm that:
- the app requested notification authorization
- the device token registration succeeded
- the push payload is the type you think it is
- the notification is being tested on a real device
The simulator has historically not been the right place to validate full APNs delivery behavior.
A Practical Debugging Order
When didReceiveRemoteNotification is "not called," walk this order:
- confirm notification permission
- confirm APNs registration succeeded
- identify whether the push is visible or silent
- identify whether the app is foreground, background, or launched from a tap
- verify the correct delegate or app callback is implemented for that scenario
That sequence solves most notification callback confusion quickly.
Common Pitfalls
- Expecting
didReceiveRemoteNotificationto handle every notification scenario on iOS10. - Forgetting to assign
UNUserNotificationCenter.current().delegate. - Sending an alert notification while expecting silent-push behavior.
- Missing the
Remote notificationsbackground capability for silent pushes. - Testing only in the simulator instead of validating on a real device.
Summary
- On iOS
10, push handling is split across several callbacks depending on app state and payload type. - Foreground and tap handling usually go through
UNUserNotificationCenterDelegate. - Silent pushes use
didReceiveRemoteNotificationwith the fetch completion handler. - Authorization, APNs registration, payload content, and background capabilities all matter.
- Debug notification delivery by exact scenario, not as one generic push path.

