I'd like to create a user account on the server for new users of an app, but I'd also like to not ask the user to type in anything. Ideally, I'd like this to be automatic, like with Game Center.
But I'm wondering if it's possible. Is there anything I can use to uniquely identify the user? It's highly unlikely that I can find out the user's Apple ID. Also, the device ID uniquely identifies the device, not the user, so it would be useless if the user has more devices...
Is there anything else I can use?
About privacy - I don't want to find out anything behind the user's back. I have absolutely no problem with asking the user for access to their information (and if there is an API that grants me this information, it would be great if the API asks this itself). As Steve Jobs himself said, this is what privacy is all about - forcing apps to ask the user for permission before doing anything with their private data.
UDID(Unique Device Identifier) − A sequence of 40 hexadecimal characters that uniquely identify an iOS device. Since from iOS 5, Apple has deprecated the UIDevice unique identifier, that means the traditional way of getting the unique id.
UUID (Universally Unique Identifier): A sequence of 128 bits that can guarantee uniqueness across space and time, defined by RFC 4122. UDID (Unique Device Identifier): A sequence of 40 hexadecimal characters that uniquely identify an iOS device (the device's Social Security Number, if you will).
UUID. randomUUID() method generates an unique identifier for a specific installation. You have just to store that value and your user will be identified at the next launch of your application. If you only target smartphones, you can take profit of the fact that the device have telephony services.
How to Find Your iPhone and iPad's UUID. Connect your iPhone or iPad to your computer, and then open iTunes. Click the device icon at the top. Your device's UUID is hidden by default—click “Serial Number” and it will change to display your UUID.
The correct solution is to use the iCloud Key-Value Store, where you can store a unique user ID without requiring any kind of authentication or user information such as an email address.
The end result is a random UUID (nothing that actually IDENTIFIES the user), that is different for each user, but will persist across multiple devices registered to the same iCloud account.
We define a field in our iCloud KV Store, let's call it userID. When the app is launched, we first check the userID. If it's there, then we're all set with our user's unique ID. If not, then this is the first time we're running for this user. We generate a random UUID and store it in the KV Store under userID. That's all there is to it.
Our experience shows that this UUID is unique per iTunes account. If your end-users are using family sharing, those accounts will be assigned different UUIDs (which may or may not be desirable but there's nothing you can do about it). Any number of devices launching under the same iTunes account will see the same UUID.
This approach is totally legit and should be approved by Apple with no issues.
Obviously you must enable iCloud Key-Value store on Xcode under Capabilities, just turn on the iCloud Switch.
Here's a simple class that implements this concept in Objective-C:
@implementation EEUserID + (NSUUID *) getUUID { NSUUID *uuid = nil; NSString *uuidString = [[NSUbiquitousKeyValueStore defaultStore] stringForKey: @"EEUserID"]; if (uuidString == nil) { // This is our first launch for this iTunes account, so we generate random UUID and store it in iCloud: uuid = [NSUUID UUID]; [[NSUbiquitousKeyValueStore defaultStore] setString: uuid.UUIDString forKey: @"EEUserID"]; [[NSUbiquitousKeyValueStore defaultStore] synchronize]; } else { uuid = [[NSUUID alloc] initWithUUIDString: uuidString]; } return uuid; } + (NSString *) getUUIDString { NSUUID *uuid = [self getUUID]; if (uuid != nil) return uuid.UUIDString; else return nil; } + (void) load { // get changes that might have happened while this // instance of your app wasn't running [[NSUbiquitousKeyValueStore defaultStore] synchronize]; } @end
And for the header file:
#import <Foundation/Foundation.h> @interface EEUserID : NSObject + (NSUUID *) getUUID; + (NSString *) getUUIDString; @end
To use, all you have to do is invoke:
NSString *uniqueIDForiTunesAccount = [EEUserID getUUIDString];
Enjoy.
Generate a UUID with this:
NSString *UUID() { CFUUIDRef cfuuid = CFUUIDCreate(NULL); NSString *uuid = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, cfuuid); CFRelease(cfuuid); return uuid; }
Nothing here is deprecated or frowned on by Apple -- in fact, it is the way they suggest you do it. Store the generated UUID in the keychain and it will be there -- even if the user uninstalls and reinstalls your app. The UUID is unique for the device and the time it was generated.
You can then use various schemes to have the user group their devices together -- iCloud, or some sort of key that you deliver from the server.
Good luck!
Addition:
Here's how I store it in the keychain, using the uuid as a username and generating a random password:
uuid = UUID(); [keychainItemWrapper setObject:uuid forKey:(__bridge_transfer id)kSecAttrAccount]; NSString *pass_token = randomString(10); [keychainItemWrapper setObject:pass_token forKey:(__bridge_transfer id)kSecValueData];
Note that all of this can be done without any input from the user.
Update:
MCSMKeychainItem has a great solution to UUID generation and storage with [MCSMApplicationUUIDKeychainItem applicationUUID]
. The library also has [MCSMGenericKeychainItem genericKeychainItemWithService:service username:username password:password]
. Together, these functions take care of everything mentioned above. Easy to install with CocoaPods too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With