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
Swift3/4+
Using iCloud record ID (CKRecordID). This ID will be unique for iTunes account.
let container = CKContainer.default()
container.fetchUserRecordID() {
recordID, error in
if let err = error {
print(err.localizedDescription)
}
else if recID = recordID {
print("fetched ID \(recID.recordName ?? "NA")")
}
}
For automatically created records, the ID name string is based on a UUID and is therefore guaranteed to be unique.
Please note that if device doesn’t have an iCloud account, or has an iCloud account with restricted access, this returns CKError.Code.notAuthenticated error
Radu
Excellent question. We have resolved the issue you describe by integrating Urban Airship (urbanairship.com) into our apps. Urban Airship offers a grab bag of functionality to support in-app purchases, receipt validation, subscription recovery, content delivery, and Apple Push Notification.
One of the great things about Urban Airship is it's ability to identify a "user", not a device, but a "user" by email address. It's not really an advertised "feature"... more of a by-product of its intended functionality.
Here is what we have found and how we can leverage Urban Airship to solve the problem you have.
When a user installs your app that has Urban Airship integrated to it, UA somehow generates a UDID-like number, which at the moment, simply identifies the device.
However, if you leverage the subscription recovery components of Urban Airship you can have the user enter an email address. Once the user enters their email address on the first device... that generated ID becomes their main method of user identification and is associated with that email address. When they enter their email address on subsequent devices, Urban Airship will trigger an email validation process. Once the user completes the validation process it updates the ID on the new device to be the same as the ID of the first device and so on. The best part of it is... it's all auto-magic! You simply integrate the components and have the user enter their email address. You should be able to have it all up and working within an hour.
It also offers functionality to allow the user to change the email address associated with all of their devices.
We have actually implemented and it works VERY well!
NOTE: As of JULY 1st 2013 Urban Airship is deprecating the subscription & recovery functionality
It is not an absolute sure solution (and only works when iCloud enabled), but it is very easy to implement: Generate a unique ID once (like UUID) and store it in iCloud key-value-storage.
The only problem is that advanced users know how to delete content from the iCloud.
To prevent the user just editing the unique ID stored in iCloud to someone else ID you can add some kind of secret to.
Today our APP was rejected, becouse of Game Center user identification. It is in App Store Guidelines: https://developer.apple.com/appstore/resources/approval/guidelines.html .
You can not use uniqe Game Center ID in G: format.
The only way now for us is to use iOS6 Facebook integration.
UPDATE: Our new version with automatic FB logon passed review process and is available on App Store ( Slovni Duel ). Uses also inApp subscription linked to FB profile.
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.
How about using game center and iCloud together to identify user?
It is less likely a user do not play game and do not sync their data.