I am wondering how to manage Apple Push Notifications when many users are on the same device for the same app, because the device token is unique per device.
If I have 2 registered users on my app on the same device, how to prevent the push notification to appear if the notification is for userA but userB is currently logged into the app?
If the app is in the foreground, that could be easily managed by an userid that prevents the code to be executed if the APN is not for this user.
But how to handle this if the app is in the background? The device will received the APN, will sound an alert, and will display the notification whatever user is currently logged into the app...
Based on your comment about being able to handle the situation if the app is in the foreground, I assume the notification has some info identifying the user the notification is for. It seems like if you store some info identifying the current user logged in, in NSUserDefaults
, you should be able to retrieve that info in didReceiveRemoteNotification
and based on that decide if the notification should be handled or not.
Update adding more info:
You will also need to implement application:didReceiveRemoteNotification:fetchCompletionHandler and turn your notification into a "silent" notification, then after you have filtered out the ones you want to display from the ones you want to suppress, you would create local notifications for those that you want to show. You also need to add a UIBackgroundModes in your info.plist and include a "content-available", key in your payload. See here for more details.
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>
It's critical to implement the version with fetchCompletionHandler since the one without that is not called when the app is in background.
Here is an example from one of my apps, that receives "silent" notifications for location update requests, and also receives some "non-silent" notifications. If the app is active I show a "toast", if the app is in the background I create a local notification from the remote notification and then trigger it.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void ) {
log?.info("******* got a remote message = \(userInfo) *******")
let message: String = (userInfo["message"] ?? "stop") as! String
log?.info("message = \(message)")
switch message {
case "update_locations":
log?.info("starting location update cycle")
locationUploader?.startUploading(handler)
case "micropost_created":
log?.info("got a new micropost notification")
let notification = UILocalNotification()
let userName = userInfo["user_name"] as? String ?? ""
let content = userInfo["content"] as? String ?? ""
notification.alertTitle = "Micropost from \(userName)"
let alertBody = "\(userName) said: \(content)"
notification.alertBody = alertBody
notification.soundName = UILocalNotificationDefaultSoundName
application.presentLocalNotificationNow(notification)
if let topMostView = application.keyWindow {
topMostView.makeToast(message: alertBody)
}
handler(.NewData)
default:
handler(.NoData)
}
}