Device identifier for push notification, devices database management.. (IOS) - ios

I've already googled this problem, but I've not get any result..
the question is: how can I register a device with a unique identifier in my DB?
I know that:
- the use of the UDID is deprecated so Apple reject app that use it.
- the identifierForVendor can change if I reinstall my app two or more times.
- I can use a user registration to get a unique identification, but I think that isn’t the correct way
Right now I use that code:
NSString *deviceUuid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
What is the best way to resolve this problem?

You can only use the Device Token for Apple Push Notification. The push notification server API will only accept Device tokens and will also check if you are allowed to sent a notification to that installation by checking the Certificate.
The Device token is unique for your app on a specific device. If the user has multiple device he/she will also have multiple device tokens (one for each install of your app).
When the user deletes you app and reinstalls it the device token can also change.
Also, as you rightly mentioned in your question, the UDID is no longer useable by developers, Apple has restricted the use of the UDID.

You should consider strategies for identifying and authorizing the user instead of the device. Depending on a device-specific identifier prevents authorized users from switching devices without some sort of administrator interaction, and allows non-authorized users access if they happen to find/steal/borrow an authorized device. You can avoid these problems by relying on user credentials instead of device identifiers. Accepted answer iOS7 - Device unique identifier.
so you should use
-(void)setAuthorizationToken:(NSString )authorizationToken;
-(NSString)authorizationToken;
-(void)setIPhoneToken:(NSString *)iPhoneToken;
-(Nsstring *)iPhoneToken:(NSString *)iPhoneToken;

Related

iOS Push Notifications - device token management

I am adding Push Notifications to my app and I know I need to store the device tokens in my database so that I can send push notifications to specific devices (or all devices).
My question is what is the best practice for maintenance of these device tokens? I can store all device tokens as they are received, but how can I detect and remove old device tokens that are no longer valid? I assume a device token can become invalid if user deletes the app, or if user turns off notifications for the app.
Update - Having a user authentication and linking it to the device token (and updating based on login/logout) makes sense. But what about if the user deletes the app? there is no logout, how do you remove the device token then?
The Apple feedback service is no longer used. Instead we have to look for a response status of 401 from the apple push notification service to determine that a token is invalid.
To test this in a development environment. Use the trick below (it says it's for feedback service, but should work with the new status code from APNS as well)
How to test Apple Push Notifications Feedback Service?
Use the APNS feedback service, to find the device tokens that belonged to an app that was uninstalled.
See this apple documentation
If you are using something like Amazon SNS for push notifications, you can use their API to get list of disabled arns and remove the corresponding device tokens from your database.
Make an webservice which stores user's device token in database for particular user. Call this webservice only if user is logged in or you have identify user as per your requirement. You need to call this webservice when device successfully register for notification and if user is not identify (i.e. not logged-in) then call this service after login api.
Also pass device token when in login and register API if you have according to your flow and replace device token for particular user.
And when user logout just unregister for notification
As you said in your last statement I assume a device token can become invalid if user deletes the app, or if user turns off notifications for the app.
General scenario is when user again login to the app or register to the app you need to again take the device token from the user and need to store it in your database
Suppose I had one app and again I install only that at that time whenever I login again to the app at that time the api must having parameter for deviceID so whenever api call happen for login at that time new device token take place in your database by just replacing the old one. Same thing will happen for new register with that app.
Hope above description help you. :)
Your app server won't know if a particular app has been forcefully deleted & your server would still have let's say token T1 mapped to deleted app/device let's say A1. Now, it may be possible that another valid user (A2) comes up with same device token T1. You just need to make sure that at any point of time one device token (i.e. T1) is mapped to only one device (the device which has provided the T1 latest). All other older device token mappings i.e. A1-T1 shall be deleted at this point else A2 might receive A1's notifications.

Can one use the deviceToken in the callback didRegisterForRemoteNotificationsWithDeviceToken to uniquely identify a device

When device is registered for remote push notification the following method is called back.
(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
My question is
Can one use this(deviceToken) to uniquely identify device. If yes then what is the life cycle(I mean is it really uniq) of this?
Under what circumstances can the deviceToken provided can change?
If this is uniq per device till the life of device(for a particular app vendor) then can one use this as an alternative over Unique Identification of iOS device ?
Edit
I intended to write device in the question heading but wrote user.
To your first question - push device token is not linked to a user. If same user login to another device he shall get a different token and if another user login to the same device, he shall also share the token with user 1.
And to answer both second & third question, here is a sample text from Apple documentation:
The form of this phase of token trust ensures that only APNs generates
the token which it will later honor, and it can assure itself that a
token handed to it by a device is the same token that it previously
provisioned for that particular device—and only for that device.
If the user restores backup data to a new device or reinstalls the
operating system, the device token changes.
So, crux of the matter is device push token shall never be used as an alternative to unique identifier or UUID.
EDIT: Per OP edit, as per above Apple documentation, since push device token can change, it should not be considered as unique identifier for a device.

iOS APNS device ID not matching Passbook Device ID

I have an (PhoneGap) App that will successfully get Passbook Passes and will also successfully receive Push Notifications separate from Passbook (when faking the device ID).
The problem I am having is that the device ID passbook sends to register the device does not match the APNS device ID. And even worse, I cannot for the life of me make the device get a different ID (even after multiple APNS certs and the uninstalling, setting date ahead technique)
Launch app
APNS yes/no? Yes!
Call for APNS device ID is received (same one as always)
Go ahead and create passbook pass, add pass
Passbook makes callback (register device) with device ID received from Apple different than APNS device ID
Both are using the same CSR file to create APNS and pass type id, an active provisioning profile (with push and passbook enabled). I'm not sure what the problem is, but half the problem is that APNS will not give it a new ID.
What am I doing wrong here? I'm assuming I'm not crazy and the device IDs should match.
Thanks
As others have commented, this is expected.
Refer to Passbook Programming Guide: Updating a Pass
specifically -
The device library identifier is a Passbook-specific shared secret between the user’s device and your web server. It is not related to the device identifier (UDID). The device identifies itself with a different ID to different servers and it may change its ID at any time. Its purpose is to allow efficient communication between the device and your server, not to let your server keep a list of of what passes are currently installed on a device. The device library identifier uniquely identifies a device and indicates that the entity making the request is authorized to make such a request.
and also from Local and Push Notitifcation Programming Guide
Note: A device token is not the same thing as the device UDID returned by the identifierForVendor or uniqueIdentifier property of UIDevice or any other similar properties such as the advertisingIdentifier property of ASIdentifierManager.
Apple goes to some lengths to prevent the facilitation of unintentional tracking, so different frameworks will return different device identifiers on the same device for a given App. Different Apps on the same device will also obtain different identifiers from the same frameworks.
EDIT - The Pushtoken (also supplied at registration) is used to identify the device in subsequent push notifications, not the DeviceLibraryID, but the concept is the same - this identifier is unique to other identifiers on the same device.

Are Push Notifications tokens unique to Mac & iOS?

By that I mean: If you have an app running on both platform, can you be sure that a given token on iOS isn't attributed to Mac? I'm pretty sure this isn't something we can "know" (Apple internal) and I shouldn't assume it, but I'm really curious what happens if you (by mistake) send an "iOS" Push (intended for your iOS App) to a Mac token. Could it reach another iOS user?! I guess potentially...
Imagine the following case (simplified):
You know you have to send a push to the token "foo" to your Mac app.
You mistakenly send a push to "foo" on your iOS app.
I hope it would land in void land / you'd get an error back from APNS but I guess it might also land on a "random" user of your iOS app, which is not the user intended (on the Mac app)
Sending a push notification requires an SSL certificate from Apple that is bound to your iOS or Mac application. Therefore it can not happen that a notification for an iOS app is sent to a Mac app.
From the following quote it doesn't seem possible that the same device token will be assigned to both an iOS device and a Mac (or to two iOS devices or to two Macs), since device tokens contain device IDs, and device IDs should be unique (otherwise they wouldn't be very useful IDs).
Every notification that a provider sends to APNs for delivery to a device must be accompanied by the device token it obtained from an application on that device. APNs decrypts the token using the token key, thereby ensuring that the notification is valid. It then uses the device ID contained in the device token to determine the destination device for the notification.
(Source)

didFailToRegisterForRemoteNotificationsWithError: user refused error?

If the user refuses the enable push notifications, we'll get an error, through didFailToRegisterForRemoteNotificationsWithError. Does anybody know what the code in the NSError object will be in this case (to differentiate it from, say, no connection being available)?
I don't think your initial statement (always) holds true. If an app is properly signed with a valid provisioning profile, calling registerForRemoteNotificationTypes: will result in application:didRegisterForRemoteNotificationsWithDeviceToken: regardless of the user's Notifications choices in the Settings app. From my experience, the only times I have seen application:didFailToRegisterForRemoteNotificationsWithError: get called was because of an improperly signed app. The error in question mentioned "no valid aps-environment entitlement found for application".
Although this question is old, and agree with most of the #Jerred's answer, i thought of posting an updated answer anyway.
The answer to main question in the thread is NO.
application:didFailToRegisterForRemoteNotificationsWithError: gets called when the app is signed with incorrect provisioning profile.
Also,
application:didRegisterForRemoteNotificationsWithDeviceToken: gets called only when user enables at-least one of the badge, banner/alert or sound setting in the notification center (in Settings app) for your app.
There are scenarios where iOS will not call either of these methods
When user refuses to grant permissions for app to send push notifications
When there is no network connectivity and user granted permissions to send push notifications.
When user disables the push notifications for app from notification center in Settings app.
To my experience, didFailToRegisterForRemoteNotificationsWithError: method is reserved for more serious cases which prevents the app from even showing the notification permission request dialog to the user. The cases that I know of include the app being run on devices that do not support push notifications, (e.g. Simulator) or some misconfiguration in the aps-environment entitlement in the app binary.
For me there was 2 files that held the entitlements, here I added Aps-enviroment : production and it worked after

Resources