Use Keychain To Store Device Identifier - ios

I noticed that my identifierForVendor always changes. Someone told me that it doesn't change when you download from iTunes. I'm not so sure about it, though. So, I want to store the first identifierForVendor generated. I found this class, JNKeychain from one of the posts i checked. It can store password and other data. I tried using that to store my identifierForVendor. Even after deleting my app and reinstalling using XCode, I was able to get the value I stored. Sounds good because this way, my identifierForVendor can persist regardless of whether it was downloaded from iTunes or not. However, I"m not very familiar with Keychain. I didn't even know we can store secure data using it. I read their documentation and it says there it's usually used to share data between applications and your apps should have same provisioning profile etc... I don't plan on sharing. I just want it to save my identifier so this is not a concern for me. My only concern is how long will my data last in the keychain storage? Will it be deleted after some time? or when I turn off my device? When i update ios version? Can it persist forever? Will keychain have a different behavior if I use developer/distribution profile?

The keychain entry will last as long as the device is not wiped or hard-reset or until the app deletes it. Apps can be deleted and replaced, but the keychain entry will remain. If an app from developer profile is overlaid with enterprise profile or app store the keychain entry should be fine.

Related

How to get Unique DeviceID from Xamarin IOS

I have a requirement wherein I should not allow the user to install my app in more than 1 device. This is an enterprise application and I distributed this using Enterprise developer account. Based on the Google search I use IdentifierForVendor to get unique device ID, but this doesn't seem to work now as when the user uninstalls and installs the new/same version of the app in the same device again, it returns new DeviceID. Now I am back to my old question - How to find a DeviceID for IOS?
What I think is a possible approach is to deactivate the DeviceID when the user uninstalls the application. But I am not sure how to achieve this as there are no cycle/function calls when the app is uninstalled.
Apple documentation says if all the apps from the same vendor is uninstalled from the device, then at the time of new installation of any app from that vendor will take new IdentifierForVendor.
So I would suggest store this unique id in Keychain and whenever you open the app check if there is any unique id stored in keychain if not then generate one and keep it there.
If app in uninstalled also , the key will be still there.
After you re-install the app , when you access the key in keychain it'll be still there.
This way you can achieve your objective of uniquely tracking a device.
Talking of keychain , it's worthwhile to take a look at Xamarin.Essentials Nuget.It provides many cross platform features including keychain.
Hope this helps.

Store UIDevice identifierForVendor in keychain rejection risks

I need to be able to identify an iOS device across uninstalls/reinstalls.
To do so, I plan to store the identifierForVendor in the keychain at first install, and retrieve it on following installs.
Is there any risk of being rejected of the AppStore by doing so?
I've seen several questions about that so I guess it would be allowed, but the Developer Program License Agreement states that:
Further, neither You nor Your Application will use any permanent,
device-based identifier, or any data derived therefrom, for purposes
of uniquely identifying a device.
I could also use a NSUUID instead, would it be safer?
Edit: add some context for answers suggesting to implement a login.
My app already has an identification system (with a login). It allows the user to connect to his account, and he should be able to see a list of the devices linked (i.e. from which he did connect at some point) to its account, in order to monitor or to unlink them.
The problem is that the identifierForVendor changes after an uninstall/reinstall of the app, leaving a "ghost" device in the user's list. Storing and retrieving it would allow a reinstall of the app not to be considered as a new device. It would only be used for this, and not for advertising or tracking in any way.
TL;DR:
Storing UUID in phone's Keychain will not get your app rejected. So don't worry.
The UUID you're trying to use is NOT a permanent identifier as we know, and storing them does not violate the licensing term that you quoted. Apple deprecated UDID's, MAC addresses, IMEI number etc. to prevent developers from tracking/spamming users based on their unique ID's. This is a privacy problem. Since UUID is a temporary ID, we are free to store them and use them later on, which does not do harm to the user.
I am quoting this from the link from Apple's resources here: Using identifierForVendor
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.
-----****UPDATE IN IOS 10.3:****-----
It seems that Apple has made some changes to how Keychain works in iOS 10.3+. Keychain items stored in the Keychain will be deleted when the all the apps from the specific vendor are uninstalled. According to Apple, the residence of sensitive information of an app even after the app is gone from the device may lead to security risks, so they decided to forbid this kind of behavior.
Developers relying on Keychain storage even after an uninstall for their apps can make use of this WORKAROUND to continue with the intended functionality. According to this workaround, any app can access the information stored in that specific Keychain Access Group, so it is recommended that adding an extra layer of encryption to your data will protect it with even more security, although keychain encrypts items by default.
You may generate a device-id(->similar to UUID) on the server and store that in Keychain of iOS. If your app is reinstalled on the device and you find that device-id in the keychain, then you will be able to identify the device.

Is there any issue with iOS app store approval if I stored UUID in keychain

I want to get the same device identifier when the app is reinstalled. So from my research I got a conclusion that when I need to get something after app uninstallation I have to store it in the keychain. I decided to store UUID in the keychain. Now I want to know is there any problem with the app store approval if I stored UUID in the keychain. Also tell me if there is any other way to do this?
I have an app on the store with regular updates in which I am storing device id in the keychain. And faced no issue from apple. Here is the Id I am talking about.
UIDevice.currentDevice().identifierForVendor?.UUIDString
No, there is no problem with this, because actually you do not store the real UUID of the device. You are not able to access it since iOS 7. All you can store is just identifierForVendor which is unique for the device and your vendor account.
UUID of device can be accessed only by owner of the device.
identifierForVendor changes whenever you remove every app from the same vendor on the device.

Does iOS clean keychain items automatically?

I use KeychainItemWrapper to store an identifier of my users in keychain of iOS. I noticed that when we uninstall the app, the identifier persist in the keychain yet; but I'm wonder Does iOS will clean the items automatically when the keychain goes so big? or some other applications can remove or access the items?
It will be deleted if the device is wiped or restored, whatever that resets your device.
Access to the keychain is tied to the provisioning profile used to sign the app. Consequently no other apps would be able to access that app's keychain info. This answers your question about some other App being able to access your App's keychain items or not.
For reference: Same Question on Apple Developer Forum

Application preferences after remove app

Is application preference stay after remove app, or after reinstall app I get cleared preferences?
I save UUID in preferences and want to know is there will be same UUID if I remove app and reinstall it after long time.
Update:
Is preferences backed up with iCloud and(or) iTunes and restore after reinstall app?
Thanks a lot!
Applications are stored in a sandbox. This means every application has its own directory, its own working space.
In that working space all data of the application gets stored. This includes documents, library files, temporary files, the application bundle, as well as the preferences file.
When a user chooses to delete an app, the whole sandbox gets removed, including those preferences.
You the answer is yes. When a user deletes and reinstals your application, his preferences will be reset.
I can tell that NSUserDefaults keep info after reinstalling app.
After removing nothing will be saved, I guess.
You can make hash from device UDID and make it unique identifier for you customers.
Don't save or transport unhasned UDIDs without users permission! Keep it hashed. You can recount hash after reinstalling or removing and another installing and it will be the same every time.
Not exactly about settings, but I hope it will help you.

Resources