I am having an issue with scheduling a local notification in an iOS 10 device when using iOS 9.3 SDK, when app is in foreground. Our application is designed in such a way that if we receive a remote notification and application is currently in foreground, we repost it to local so the user can still see the notification when they put the app in background. This works in iOS 9 devices, but not in iOS 10.
Repost code:
dispatch_async(dispatch_get_main_queue(), {
let localNotification = UILocalNotification()
localNotification.userInfo = userInfo;
localNotification.fireDate = NSDate()
localNotification.timeZone = NSTimeZone.localTimeZone()
localNotification.soundName = UILocalNotificationDefaultSoundName
if let apnsPayload = userInfo["aps"] {
if let alert = apnsPayload["alert"] as? NSDictionary {
if let message = alert["body"] as? String {
localNotification.alertBody = message
}
}
if let category = apnsPayload["category"] {
localNotification.category = category as? String
}
}
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
})
I believe the reposting with scheduleLocalNotification
is working somewhat correctly because I can see that my didReceiveLocalNotification
delegate is getting called in AppDelegate
. However, if I pull the notification drop down when putting app in foreground or background there is no notification present.
Has anyone else run into this problem? I have seen a lost of posts with how to use iOS 10 UNUserNotificationCenter
, but I do not have access to this in iOS 9.3 SDK.
This seems to be just the new expected handling in iOS 10. If you post a notification while app is in foreground, it will call the didReceiveLocalNotification
delegate, however it will not post it to the notification center tray.
To get around this, I am now storing all received notifications in a static array, and then when app goes to background I will schedule the notifications to be sent in 5 seconds, just to give the app time enough to completely go to background.
Creating/Appending the notifications:
/**
Takes a given Dictionary that should correspond to a Remote notification and reposts it (at current time)
as a Local Notification. If the app is in the foreground, then no banner, alert, or sound will play, but the
notification should appear in the Notification Center.
- parameter userInfo: Dictionary that should correspond to a Remote notification.
*/
static func repostLocalNotificationUsingRemote(userInfo: Dictionary<NSObject, AnyObject>) {
let localNotification = UILocalNotification()
localNotification.userInfo = userInfo;
localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
localNotification.timeZone = NSTimeZone.localTimeZone()
localNotification.soundName = UILocalNotificationDefaultSoundName
if let apnsPayload = userInfo["aps"] {
if let alert = apnsPayload["alert"] as? NSDictionary {
if let message = alert["body"] as? String {
localNotification.alertBody = message
}
}
if let category = apnsPayload["category"] {
localNotification.category = category as? String
}
}
// Add notification to queue
localNotificationQueue.append(localNotification)
}
Eventually Sending, called in applicationDidEnterBackground
and applicationWillTerminate
:
/**
Posts all pending notifications that were received while app was in foreground.
*/
static func postPendingLocalNotificationIfAny() {
for localNotification in localNotificationQueue {
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
localNotificationQueue.removeAll();
}
Ideally we will be updating to iOS 10 SDK and use UNUserNotificationCenter
to display notifications in the app, but until then this change matches are current iOS 9 behavior.