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.
Related
I have a strange case with APNS.
A user has two devices with the same Apple ID and our app installed. Both devices return the same APNS token to my app.
Whenever I try to send a push notification, the older device receives it, though we want the newer device (the one that the app was installed to recently) to receive it.
How do I achieve this?
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;
We have developed an iOS app that makes use of push notifications.
Our client wants to distribute the app through their own MDM server. This means they'll compile and sign the app themselves and also have the appropriate APNS certificate, which we include in our server-side application. So far, so good.
Now, the client also wants to distribute the app to other devices that aren't connected to the MDM server. This would mean a different (AdHoc, App Store, ...) distribution channel with a different certificate chain.
How should we handle this on our server side where we send the push notifications to the APNS?
Can we just send every push notification twice, once with each certificate? Do we need to determine which app installation requires which device (depending on the distribution channel)?
This is basically dependent on the way you distribute the app. When distributing if the application identifier is the same it will refer to same app. If it different only it will install multiple times. Means if you have the same app id in both cases its enough to send one notification so that no matter how you distribute it will send the notification. In case if you have changed the app ids yes you have to send that multiple times. Another thing you may do is to change the app id slightly and introduce a wildcard for app id. Which is also fine to send one notification.
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)
We added receiving push notifications to an iPhone app. Everything was working in the test/sandbox environment, we were getting token id's from the app and could send push notifications from our server.
But now the app is approved and came out of the Appstore we were getting empty push tokens/notifications id's send to our server. We already have over 600 of them... Note that end users do get the popup to approve of receiving notifications in the app, the app is just sending empty tokens to our server after approval. So probably empty tokens are handed out by the APNS server.
The following issue showed us that this is probably due to missing 'push notification' entitlement in the provisioning profile we used to make the build for the app store:
How do I check if an iOS distribution provisioning profile has push notifications enabled?
The missing entitlement was due to a bug in Apple's provisiong protal website, but after 'Modify any existing profile before you download the new one' as mentioned in the following article
http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ProvisioningDevelopment/ProvisioningDevelopment.html
We now have the correct entitlement in our .mobileprovision file:
<key>Entitlements</key>
<dict>
..
<key>aps-environment</key>
<string>production</string>
..
So we are rebuilding our app and adding it to the store. And hoping to get push notifications then.
I hope the above might help some others. But now to get to my actual question: Will we start receiving new push tokens also for the 600+ users that already downloaded the current version when they install the next update out of the store? Or do we need to add some initial code to our app? The registerForRemoteNotifications method is right now only called on application startup. Will it also be triggered when the push token id is changed from empty ('') to an actual token? Of course we do not want to wait another (small) week for the new AppStore approval and only then find out that push notification still aren't working for some users. I'm hoping some expert out there can tell us.
Note: We are using an iPhone app developed in MonoTouch, and using the (old) APNS-Sharp library to send the notifications from our server, but I don't think those details are relevant for this issue.
When those 600+ users install the next update and run the application again, your application will call registerForRemoteNotifications (since you said you call it on startup), and will get the non empty device token (when application:didRegisterForRemoteNotificationsWithDeviceToken: is called).
Apple state in their docs that you should always call this method at startup instead of using a cached copy of the device token, because the device token is not guaranteed to remain the same. So you shouldn't have any problem.
Here's the relevant quote from the APNS docs :
An application should register every time it launches and give its
provider the current token. It calls
the registerForRemoteNotificationTypes: method to kick off the
registration process. The parameter of this method takes a
UIRemoteNotificationType (or, for OS X, a NSRemoteNotificationType)
bit mask that specifies the initial types of notifications that the
application wishes to receive—for example, icon-badging and sounds,
but not alert messages. In iOS, users can thereafter modify the
enabled notification types in the Notifications preference of the
Settings application. In both iOS and OS X, you can retrieve the
currently enabled notification types by calling the
enabledRemoteNotificationTypes method. The operating system does not
badge icons, display alert messages, or play alert sounds if any of
these notifications types are not enabled, even if they are specified
in the notification payload.
This is also relevant :
By requesting the device token and passing it to the provider every
time your application launches, you help to ensure that the provider
has the current token for the device. If a user restores a backup to a
device or computer other than the one that the backup was created for
(for example, the user migrates data to a new device or computer), he
or she must launch the application at least once for it to receive
notifications again. If the user restores backup data to a new device
or computer, or reinstalls the operating system, the device token
changes. Moreover, never cache a device token and give that to your
provider; always get the token from the system whenever you need it.
If your application has previously registered, calling
registerForRemoteNotificationTypes: results in the operating system
passing the device token to the delegate immediately without incurring
additional overhead.