How can I tell if my user upgraded to a new phone, or restored from a backup in iOS? - ios

I want to make getting a new device as easy as possible in my iOS app.
However, I want to ensure that the old instance of the app (and more importantly the data) is no longer accessible on the old phone.
How can I track the uniqueness of a phone, and if the app has been installed on more than one device?
My goal isn't to control licensing, but rather to make sure the user knows what is "out there".
(My app stores private keys in the app container, and I want to ensure these keys don't fall into the wrong hands... hence the reason for my question)

UIDevice offers identifierForVendor
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.

Related

Different UUID in swift 2.2

Before Swift 2.2 the UUID value was the same every time I opened the app, now changes at every opening
I use this code:
UIDevice.currentDevice().identifierForVendor!.UUIDString
How can I do now to identify the user?
Every time you delete the app, the UUID may change.
If you just close and open the app, it's should be the same.
But if you delete the app (or install it again via xcode), it might change.
There are a couple of answers that explain why the UUID is resetting. There's one that offers a potential work around, but I'd consider it far from ideal. But I want to highlight something important about the way UUID's work that serves as a great workaround that has absolutely zero impact on the production OR debug version of your code base or compiled binary.
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.
All you have to do to prevent this value from changing while developing App-A is to simply install App-B from the same vendor (yourself) and keep it installed during the life time of App-A's development. This is literally as simple as starting a blank new iOS project and install the blank slate to your test device (using the same developer account & such), and then never uninstall it again during development.
App-B keeps a constant UUID for the vendor (yourself) so no matter how many times you delete and reinstall App-A, it will always keep the same UUID.
This actually seems to be a bug IMO. Everytime I run my app in the simulator it generates a new Vendor ID. You can probably get round it by storing the ID into NSUserDefaults on the first bootup then retrieving / comparing the value from NSUserDefaults instead of getting it from identifierForVendor. This will save a static vendor id in defaults but in theory the vendor id will still be changing every boot up.
Kind Regards,
Krivvenz.
Update: I can confirm I have installed multiple apps on the same simulator too but the vendor ID is still changing on every boot.
Update 2: - I have logged this as a bug with Apple - 26195931.
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.
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.
Refer this link for more info.

iOS 8 Unique Identifier (Serial Number preferred)

I am working on an enterprise app and need access to programmatically retrieve the device's serial number. Is there an API or any documentation on how to retrieve this in iOS 8? From what I can tell, this functionality has been removed in iOS 8.
Is there a suitable replacement identifier for the serial? I need something that is reliable and will never change even if the device is reset.
It will be for enterprise usage so App Store approval is not a concern.
You're up a creek here. The two "tracking" features are Advertising Identifier and Identifier for Vendor. The former can be reset within the Settings app quite easily while the latter will reset once the user uninstalls all apps with the root bundle identifier associated with the app suite. Both also change with a device reset of course.
If you're deploying the app with an MDM solution you will have access to that device's UDID as it still flows forward to MDM servers, you just can't access it programmatically in your code. The complete deprecation of UDID, serial number and MAC address (even with private APIs) stomped all over some custom utilities I wrote within our Enterprise to try and accomplish something similar to what you're looking to do. If you find somethingthats consistent I'd love to see the follow-up!
EDIT:
I had an epiphany while circling back to this situation again. If you are in fact using AirWatch (I can't speak to Mobile Iron, etc) you can setup the console to send a keychain value to each device at the time of app install. From there the app will be able to consume the value AirWatch sends down. The same goes for any attribute that AirWatch harvests for the device (serial, UDID, MAC, etc). While this workaround comes with a big caveat (using AirWatch for deployment) it will work. Since Apple neutered all Serial Number work arounds win iOS8 this is the most viable option I have found.

Alternative to [UIDevice currentDevice].identifierForVendor

I have one product that has two different applications. and both the applications it gives me different Identifiers for the same device (you would assume that apple would associate this to maybe your developer account so that you can reuse the information across your applications), but I was wondering is their anything that would give me the same identifier for a device on both the applications?
identifierForVendor is really what you want. UDID is a big NO on the AppStore. A user can opt out to advertisingIdentifier. Other ways (by MAC address, like ODIN1, and solutions that rely on UIPasteboard, as OpenUDID) will break on the future (hint: 7).
According to the docs, you should have the same identifier if both apps are from the same developer:
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.
The value of this property may be nil if the app is running in the background, before the user has unlocked the device the first time after the device has been restarted. If the value is nil, wait and get the value again later.
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. Therefore, if your app stores the value of this property anywhere, you should gracefully handle situations where the identifier changes.
OpenUDID is the best solution until now, even if it also may be changed if the device is reset.

Pasteboard not accessible when locked with passcode on iOS

I have noticed I cannot access the Pasteboard in iOS whenever my device is locked with passcode. I know there was a restriction regarding keychain, but not sure why its affecting pasteboard as well. Is this a known issue or purposeful restriction?
I'm assuming this is desired function.
Imagine an app like 1Password. That app supports copying a password to the paste/clip board.
If I have a passcode set on my device, it's probably because I don't want people to be able to see the data on that device - it could contain stuff like, say, all the specs and launch date for the next iPad.
As a user, I probably shouldn't be copying such information to the pasteboard, but, hey - my device is locked with a passcode, right? No one can see my info, right?
Apple knows that users often use this line of reasoning, and, however flawed it may be, you build your OS for the user - not the user for your OS.*
* Unless you're Microsoft building Windows 8. Then you can break all the rules and make a strange OS.

Store settings ios5

My iOS app has a need to uniquely identify each device so it can retrieve files that it has uploaded to the server with as little user interaction as possible (IE we don't want the user to have to have a username and password). With the release of iOS5, apple has deprecated the UDIDs which would have been the easiest way to go about this. The other way would be to generate and store an identifier on the device and read it from there every time. However, apple could at any time delete the files because they feel there isn't enough free space on the device.
Is there a way to store a device identifier on the local filesystem without worrying about apple "cleaning" it for me?
Or if there's not, how would I go about generating a device identifier that would be the same for one device no matter how many times I generated it but still different from all other identifiers?
You can use the Wireless NIC's MAC Address as the unique identifier.
Also, any files in the Documents directory will not be wiped by apple and will be sync'ed via iCloud. Apple says all generated content should NOT go in the Documents directory (at least if it can be regenerated).
To get the MAC Address I used code from this post: How can I programmatically get the MAC address of an iphone.

Resources