After warning from Apple, apps using UDIDs now being rejected
UDIDs are now gone.
But it’s easy enough if you need a device unique identifier to generate one and track the device that way. Of course because you have your own unique identifier you cannot match numbers against other software makers, and you can’t guarantee the user will uninstall and reinstall the application–but on the other hand, if you save the unique identifier with the device and the user upgrades his phone, the identifier will move to the new phone, following the user.
Step 1: Create a UUID.
You can create the UUID using Apple’s built in UUID routines.
CFUUIDRef ref = CFUUIDCreate(nil); uuid = (NSString *)CFUUIDCreateString(nil,ref); CFRelease(ref);
Step 2: Write the UUID out to the Documents folder, so the UUID gets backed up with the phone.
Because under the hood iOS is basically Unix, we can use the C standard library to handle creating and writing the file for us:
char buf[256]; /* HOME is the sandbox root directory for the application */ strcpy(buf,getenv("HOME")); strcat(buf,"/Documents/appuuid.data"); f = fopen(buf,"w"); fputs([uuid UTF8String], f); fclose(f);
Step 3: If the file is already there, use what’s in the file rather than generating a new UUID. (After all, that’s the whole point of this exercise; to have a stable UUID.)
Putting all of this together, we get the following routine, which can be called when your application starts up in the main UIApplicationDelegate when you load the main window:
- (void)loadUUID { char buf[256]; strcpy(buf,getenv("HOME")); strcat(buf,"/Documents/appuuid.data"); FILE *f = fopen(buf,"r"); if (f == NULL) { /* * UUID doesn't exist. Create */ CFUUIDRef ref = CFUUIDCreate(nil); uuid = (NSString *)CFUUIDCreateString(nil,ref); CFRelease(ref); /* * Write to our file */ f = fopen(buf,"w"); fputs([uuid UTF8String], f); fclose(f); } else { /* * UUID exists. Read from file */ fgets(buf,sizeof(buf),f); fclose(f); uuid = [[NSString alloc] initWithUTF8String:buf]; } }
This will set the uuid field in your AppDelegate class to a unique identifier, retaining it across application invocations.
Now any place where you would need the UDID, you can use the loaded uuid instead. This also has the nice property that the generated uuid is 36 characters long, 4 characters narrower than the 40 character UDID returned by iOS; thus, you can simply drop in the uuid into your back-end database code without having to widen the table column size of your existing back-end infrastructure. Further, because the UDID format and the uuid formats are different, you won’t get any accidental collisions between the old and new formats.