What is the best time for requesting a device token, i.e. calling UIApplication.shared.registerForRemoteNotifications()? Each time at the launch of the app, only once at the same point or only after user permission had been granted?
In case the request fails, what's the best strategy for requesting the token again? Should I request it again immediately, wait for network reconnection or do something else?
Related
I want to make sure my server always has the up to date APNS device token, which can change under specific circumstances.
Should I save it to the Keychain, and on launch check if it's different, and then update the server if so?
Is that the best way to be doing this?
Apple actually say NOT to store the device token locally. You call registerForRemoteNotifications() when you need the device token. From Apple:
Never cache a device token; always get the token from the system whenever you need it. If your app previously registered for remote notifications, calling the registerForRemoteNotifications method again does not incur any additional overhead, and iOS returns the existing device token to your app delegate immediately. In addition, iOS calls your delegate method any time the device token changes, not just in response to your app registering or re-registering.
So what you need to do is register for remote notifications on launch, and send that token to your server. From Apple:
Device tokens can change, so your app needs to reregister every time it is launched and pass the received token back to your server.
You can find more documentation here: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/IPhoneOSClientImp.html#//apple_ref/doc/uid/TP40008194-CH103-SW25
Sure thing, you need to register for push notifications every time the app is launched. Like the documentation from Apple says, you never know when and why the token can/will change.
Second, indeed you can have some code to store locally the token in case of a server error or loss of internet when you try to send it to your server. And this logic can retry with a delay and max try count. But this is pretty overkill and not KISS-like.
What you can do is send it as soon as you get it from didRegisterForPushNotification and store it locally and every time the user of your app does an "update settings" call send it at the same time also.
Do you need to register your APNS device token with GCM every time via:
tokenWithAuthorizedEntity:scope:options:handler
every time the app is launched, EVEN IF the device token is identical.
According to a sample app for GCM, every time the app is launched, [[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:_gcmSenderID [1] is called. This is because the registration is invoked from didRegisterForRemoteNotificationsWithDeviceToken which does need to be called every time the app is launched - "Device tokens can change, so your app needs to reregister every time it is launched and pass the received token back to your server." [2]
Can I store the registrationToken and deviceToken and only reregister when the deviceToken changes? The presence of GGLInstanceIDDelegate#onTokenRefresh seems to suggest that there is a mechanism to be notified when the registrationToken changes for your deviceToken, but I would like this to be confirmed.
[1]https://github.com/googlesamples/google-services/blob/master/ios/gcm/GcmExample/AppDelegate.m#L151
[2]https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/IPhoneOSClientImp.html
In Google's official GCM Client Demo App, registering every time the app starts ensures that your servers gets the Registration ID even if it lost it somehow, but that shouldn't be an issue if your Registration IDs are persisted properly in the server.
Note that google may periodically refresh the registration ID, so you should design your app that be called multiple times. Your app needs to be able to respond accordingly.
To summarize, you should always treat the Token as if it may change any time you restart your application.
I'm currently creating an app that needs to receive push notifications from a server. This app has a facebook connect part, and a logout (from facebook) part as well.
When I get the device token, I send it to my server and save it into DB with the FB_id, then when I want to send a notification to a user, I get its FB_id, and then get its device token.
My question is:
If a user decides to lend its device to a friend, I will have two FB_id for one device token. Then, the first user will receive notifications from the second one...
How can I deal with this?
I thought to delete the token on logout, but I'm not sure it's really safe...
Thanks in advance
Most documentation advises to register for remote notifications on launch, and on receipt of the token, push this to a server with any other app-specific settings (e.g. user, in-app Push settings). However, I am not sure how to handle the following corner case.
If the user launches the app without connectivity, no token will be received. Moments later, connectivity is restored. The user attempts to change some setting in the app, which should prompt a post to my server including the setting and the token. However, the token is still nil.
Would it not be better, instead, to register for notifications every time before attempting to post the setting? It seems unnecessary to request this token on launch since it might not be needed, and even worse, might be nil when it is needed.
I think it's still best to register for push notifications when the app is launched. When you get the device token, you don't have to immediately send it to your server. You can store it locally on the device. When your logic requires to send the device token (as well as other settings) to your server, get the locally saved token. If the saved token is null, try registering again, and send the token to your server once you get it.
Note that when the app is launched you should register for push notifications even if you a have a previous locally stored device token (due to the remote chance that Apple would decide to change the device token).
Apple recommends you should call register every time the app comes to the foreground ( either when you open it or when it comes back from background).
This call does not serve only as a way to get the push notification token but also to let Apple know that this application is still interested in receiving push notification. If you call this method only once, or rarely and you don't send push notifications that often, you could run into a scenario where the token you have been using, that is stored on the server is no longer a valid token (after enough time has passed without a token being acknowledged by a device apple will no longer consider the token valid. )
I'm developing an iOS app that enables the user to observe technical devices and be notified if there are problems.
What I know so far:
My app requests a token from the APNs.
My app sends this token to my server.
My server notifies the APNs in case of an event.
The APNs pushes a message onto the device.
What I want to know:
I read the token may change, therefor I need to request it on every app launch. Is this true?
If I get a new token from time to time I have to register at my server from time to time to make sure it uses the current token. Do I have to store and manually send the old token with the new one if the token changes to allow my server to delete the old one?
How can I detect that a user removed the app to remove his device on the server?
Highest priority in my case is for the server to know which devices are registered with the service. Old devices (old tokens that is) need to be removed immediately.
Thanks for your help.
You should register for the remote notification on every app launch and send the token to your server.
To check if the user removed the app or disabled notifications you have to check the feedback service. Look for it on this page:
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/BinaryProviderAPI.html#//apple_ref/doc/uid/TP40008194-CH13-SW1
Note: APNs monitors providers for their diligence in checking the feedback service and refraining from sending push notifications to nonexistent applications on devices.