iOS DeviceCheck API - Will the token remain same if user uninstall the app - ios

We want to prevent user from creating multiple profiles on same device.
For this we first tried IDFA but IDFA can be reset anytime from Settings.
Then we found DeviceCheck that states:
identifying Access per-device, per-developer data that your associated
server can use in its business logic
According to this we get to set two bits per device and a token for server to server verification. Now the question is:
If user uninstalls the app and installs again. will the token remain same?
How would we detect user isn't creating multiple Profiles on same device?

Device Check is the best solution for what you are trying to achieve. The advertising ID can be turned off and reset, and the [[UIDevice currentDevice] uniqueIdentifier] will be reset once the user uninstalls all app from a given developer.
Device Check is the solution Apple has proposed to check whether a device has redeemed an offer, created a previous profile, or simply to check whether the device is an authentic Apple device.
It requires the use of a server to communicate with Apple servers to validate a client generated token. You get two bits you can set. Those two bits are connected to your developer profile, not two bits per app.

keychain is the place where you can store users data securely. Storing data in keychain has one more advantage — in a case when the user decides to remove the app from the device and then he decides to install it again, the data is still saved.

You can also do this by storing a value in the Keychain. It will persist even if the app is deleted and thus you can tell if the app is a new install or a reinstall. So if a value is there in your keychain it is a reinstall otherwise its a fresh install.

Related

does app give different device token on re-installing again

I remember, the device token never changes upon re-installing for iPhone.
However these days (especially on iOS 9), I noticed that device token is changing if I re-install the app.
Is this setting is done by Apple or I am missing anything?
I have to know this because this is very important for me as I am sending push based for specific users to inform their updates.
Also for no reason there are un-wanted many device tokens.
Note
I am calling below webservice in App Delegate
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
// sending it to online database for my record
}
Yes on iOS9 Apple says that Device Token might change each time your app is installed. So the best way is to reregister the Device token on each launch.
Here is a link to Apples documentation about changing device token
You need to find your own way to track user. Here is issues with your approach and suggested vendor identifier:
Device push token can change at any moment. You can track this change during application launch and ask server to switch tokens, but messages which will be send till this moment on old token will be lost.
identifierForVendor - also very unreliable source of unique identifier, because it will change in a lot of cases.
The value in this property remains the same while the app (or another app from the same vendor) is installed on the iOS device. The value changes when the user deletes all of that vendor’s apps from the device and subsequently reinstalls one or more of them. The value can also change when installing test builds using Xcode or when installing an app on a device using ad-hoc distribution. Therefore, if your app stores the value of this property anywhere, you should gracefully handle situations where the identifier changes.
For single device you can use Keychain as source of persistent identifier storage. You can generate for user new unique identifier (for example with NSUUID) and store it in Keychain (if not exist yet). If access group will be configured for stored item and reused with all your application - you will have access to stored unique identifier from your applications on user device. If properly configured, item in Keychain will be stored in encrypted user device backups and even will be restored on his new device.
Yes, it might be changed when each time app is installed. you need to update the device_token on every launch of app.
rtfm:
"The value of this property is the same for apps that come from the same vendor running on the same device. A different value is returned for apps on the same device that come from different vendors, and for apps on different devices regardless of vendor."
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDevice_Class/#//apple_ref/occ/instp/UIDevice/identifierForVendor

KeyChain - what is it?

I'm writing my first app for iOS. In it conceived some protection from repetitive actions of the same user device (few, if apple account. Login "login-password" at the application level as such does not exist, therefore it was necessary to implement a hidden identification.
Convenient would it be to generate a random number that would be stored somewhere in the user, and remained unchanged even when reinstalling the app.
Started to read it. Learned about SSKeyChain. But just do not have enough experience to understand your logic... Please explain in accessible language!
My assumptions:
(please correct if I'm wrong!)
1) each user single Apple account that is attached all apps to one of the device, and thus the storage on the device. Or is the cloud for one account and multiple devices for this account (which is called keychain)?
2) has a free Access to the library SSKeyChain (via the security framework), which I for your application can write any data with their keys (the password to the app, login, color scheme)... so if you reinstall the app, it could check "are there any settings in KeyChain for me?" and take data from there. Similar to NSUserDefaults/SharedPreferences (ios/android), not receding after reinstalling the app.
3) the Possibility of losing data from KeyChain the user device is only shift Apple account any action by Apple.
So? :)
If you reinstall app,information stored in keychain is still there.But your provisioning profile should not change
From document
On iPhone, Keychain rights depend on the provisioning profile used to sign your application. Be sure to consistently use the same provisioning profile across different versions of your application.
Keychain is encrypted container and in iOS an application can access only its own keychain items.
When a user backs up iPhone data, the keychain data is backed up but the secrets in the keychain remain encrypted in the backup. The keychain password is not included in the backup. Therefore, passwords and other secrets stored in the keychain on the iPhone cannot be used by someone who gains access to an iPhone backup.
It is just an iOS provide container to save sensitive data。I do not understand what you say about Apple account.

how to detect whether user had installed this app before

I am trying to check whether user has installed this app on his iOS device before or not.
For example I install app X , then Uninstall it, and again Install it.
I want that app X be able to detect that the device had installed this app before and this is a re-installation.
Update
By thanks to all friends that shared solutions like keychain, vendor Id and etc. The main subject that I should notice (as mentioned in comments) is that; Is there a solution that works even after system restore or system factory reset? According to #Andrea's answer using receipts may work but what about the cases that we want to publish the app in enterprises account? Or what if user uses a jailbreak device and install the app with and IPA? Some times because of security problems we want to detect that whether this app is installed before or not? So how we can detect it?
Maybe trying to check the app receipt you can infer the original purchase date (even if the app is free it comes with a receipt), but this could be difficult.
If you want to do that you can can add a flag to the keychain. Keychain values persist after an uninstall, but not after a system restore.
Of course this can work only in future releases.
As the OP mentions in one comment Apple does not allow access to the device UDID so we need a different approach to uniquely identify the user.
In order to get an identifier that uniquely identifies the user you could use:
[[UIDevice currentDevice] identifierForVendor]
But be careful, according to Apple documentation:
The value in this property remains the same while the app (or another app from the same vendor) is installed on the iOS device. The value changes when the user deletes all of that vendor’s apps from the device and subsequently reinstalls one or more of them. The value can also change when installing test builds using Xcode or when installing an app on a device using ad-hoc distribution. Therefore, if your app stores the value of this property anywhere, you should gracefully handle situations where the identifier changes.
A possible solution to this is to store the identifier in NSUserDefaults and also in the server and have a logic that at startup checks if there is a change in the identifier. In that case you could update the identifier locally and in the server to provide continuity for your analytics, for example.
For example to check for a change in the identifier:
NSString *previousUUID = [[NSUserDefaults standardUserDefaults] stringForKey:DEVICE_UUID];
NSString *currentUUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
BOOL UUIDChanged = ![previousUUID isEqualToString:currentUUID];
// Handle this situation in your backend to offer continuity in your analytics
I have three apps in the App Store that use this and were approved by Apple without problems.
iOS is built to reserve a portion of disk to each application installed, when you uninstall application the space is erased so there isn't a "cookie" that describes when app has been installed.
You can reach your goal in two ways: through the keychain, for instance you save a value with specific key and you check every installation that key or through a simple backend call that send you the date o whatever you want. I think the first solution is better.
I would define a method to uniquely identify a device. Whenever an install is issued on a device, I would send a request to a server, where device keys are stored. If the key is not already present in the database, then I would store it, otherwise the install has been already issued.
You can save something to keychain and then try to read it.
You can use APNS. Apple push notification service.
Device token never will change whatever device reset.
So, you can use Push notification.
Push notification(device token) is unique for each device and always will be same.
When app will install save device token on your server database so, whenever app will again install on same device you can check device token from server database.

VPP account - will the user see a badge on the app store if an update is available?

If we distribute an app through an VPP account (Volume Purchase), will the user also get a badge on the AppStore Dashboard icon, if an update is available (like with the 'normal' user accounts?)
There is a comparison table of the VPP features for the three possible distribution paths "MDM User Assignment", "MDM Device Assignment" and "Redemption codes".
The way I understand the table is that automatic updates through the App Store are available if you distribute via redemption codes OR assign the app via MDM directly to the user / Apple ID.
Only if you assign it via MDM directly to a device (no Apple ID required), it will not have a connection to the store and therefore not provide any automatic updates. However, if you have the MDM in place, you push updates through that anyway.
Yes! After about a day — I’m not sure whether it was closer to 24 or 36 hours — every user either got auto-updated or got the badge. It just took a lot longer than you’d think. Thanks for asking — I got the email letting me know to respond or I wouldn’t have remembered to.

is there a way to check two device tokens are belongs to same device?

I want to get the device token of the device and want to send it to a server.Sometimes if I uninstall the app and install it again,Then the new device token which I got is different than previous.So,In my server there are two device tokens which are belong to same device.Can we avoid that?(In my service,I want to keep only one device token per one device)
Thank you.
If you doing this for push notification, you can use the feedback service from apple to detect if a device is deleted.
You can store a generated UUID and store it in the keychain like this. If you set it up right, it will persist between app deletes and reinstalls on the same device, but not across multiple devices via a restore from backup (unless you want that).

Resources