Is identifierForVendor different between development and distribution versions? - ios

I'm working on an update for one of my games. I had a version that I downloaded from the app store on my device, and I pressed Run in xcode... The app got updated, but I had a little scare when I noticed that the game's stats all disappeared.
Now, after looking over my code, my only theory that makes any sense is that identifierForVendor is different. I use this as part of the key to encrypt my game's data (to make it impossible to just copy data between users). If it changes, it makes perfect sense that the data is lost.
So before submitting my update, I wanted to verify that this is the case - does identifierForVendor change between development versions and distribution versions?
Thanks!

Found the answer - in the documentation, of all places :)
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDevice_Class/index.html#//apple_ref/occ/instp/UIDevice/identifierForVendor
Normally, the vendor is determined by data provided by the App Store. If the app was not installed from the app store (such as enterprise apps and apps still in development), then a vendor identifier is calculated based on the app’s bundle ID. The bundle ID is assumed to be in reverse-DNS format.
So the answer is "yes".

Related

is it possible for iOS identifierForVendor to be duplicated?

Every time I uninstall and install my app, a new identifierForVendor is generated.
I found out that it is an ongoing issue of Apple.
My follow-up question is, will it then be possible for two or more devices to have the same identifierForVendor if they keep uninstalling・reinstalling?
Teoretically yes, but for practical applications you shouldn’t need to worry about this.
identifierForVendor is of UUID type - this wiki page has a section on collision probability for UUIDs in general, not only on iOS. The short of it is that in order to have 50% chance of collision you’d need to generate ~2.71*10^18 identifiers. And thats
equivalent to generating 1 billion UUIDs per second for about 85 years. A file containing this many UUIDs, at 16 bytes per UUID, would be about 45 exabytes.
Also, I wouldn’t say that its an „issue”, but rather a decision choice made by Apple - in the documentation they clearly state that
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.

What does TestFlight do to my iOS executable?

I hash my iOS executable at launch to verify its integrity, and have had no problems doing so until TestFlight -- which appears to modify the executable as well as install it in some funky (undocumented?) way.
Even more concerning is I get multiple hash values, which appear to vary by device or iOS version or carrier or something. I don't own enough devices to be certain. But none of the hashes match the one I compute prior to uploading to TestFlight.
So I have two questions: (1) What is TestFlight doing to my executable, and is the process documented somewhere? And (2) Does the final app store release pull the same shennanigan, or something similar, or does it leave my executable unmodified from when I uploaded it?
That's what code signing is for.
Code signing your app assures users that it is from a known source and
the app hasn’t been modified since it was last signed.
Source: https://developer.apple.com/support/code-signing/
It seems like Apple encrypts your app. While this post is about App Store submission, could be the same for Test Flight (not sure about this).
See: https://stackoverflow.com/a/5784332/2019384
Also it's not recommended to verify your apps integrity by yourself, as you'll run in such issues. Besides iOS already does this for you:
Apple does not provide any supported way for you to check your app’s
integrity. iOS already does that by default.
Source: https://forums.developer.apple.com/thread/52801
In addition to d4rk's answer, if you're using Swift, Apple compiles in appropriate bits to optimize your app for each device.

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.

identifierForVendor changes on reinstall

identifierForVendor is not supposed to change on reinstall of app:
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.
https://developer.apple.com/reference/uikit/uidevice/1620059-identifierforvendor
However, I've just tested this with one of our live apps on the app store. Even with a number of other of our apps still installed on the device, if I reinstall app A the UUID returned from identifierForVendor changes every time.
It was not like this.
This used to work. But at some point, the UUID seems to have started changing on "simple reinstalls" (as stated above). Is this a known bug? Is identifierForVendor known to be broken versus the documentation above? Any workarounds (other than saving UUID to keychain, because that method breaks with iCloud syncing)?
It's a known bug. It seems like Apple made an update to AppStore that causes this new behavior for identifierForVendor around the 28:th May. If you search in the App Developer forum, there are other developers reporting the same problem.
The signature gc from Apple have replied on the issue with the following answer:
"Please file bug reports on this at https://developer.apple.com/bug-reporting>. We're aware of this issue and are investigating. There's no known workaround at this time."
identifierForVendor is expected to change when all vendor's apps are removed from the device. Also, it is bound to change if you're building and installing from Xcode directly.
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.
Source: UIKit/UIDevice/identifierForVendor
We are about to resubmit using an App Group entitlement to give us shared NSUserDefaults. It sounds like App Group NSUserDefaults (unlike keychain-access-group and iCloud key-value storage entitlements) are shared on the device, but not over the iCloud account. If the shared "deviceid" NSUserDefault key doesn't exist, we'll save the IdentifierForVendor ID and then use that for all our apps once it saved.

Updating an ad-hoc installed iOS app

Hopefully a easy(-ish) one, but I'm just wondering if it's possible to update an ad-hoc over-the-air installed iOS app (deployed using the standard $99 developer license), hence ensuring that any data stored within the app's document sandbox is still available.
Additionally if iOS 4.x file protection is used (i.e.: the NSFileProtectionComplete encrypt attribute is set on the files, etc.) will an updated app still be able to read the files?
Whilst there are some existing questions that touch on this (such as Updating enterprise iOS apps while retaining some files of the current app bundle), these don't answer this specific query and (potentially) pre-date the newer style of ad-hoc distribution.
You can definitely update an ad hoc over-the-air-installed iOS app and retain the current app data -- it appears to work identically to normal update installation.
Because it works the same way as a normal update, file protection should work the same as well, though I don't have first-hand experience.

Resources