开发者

What to use if not "IPHONE UDID"?

Wow... look at all the开发者_Go百科 "panic stories" online this week regarding using an iPhone's UDID.

 [[UIDevice currentDevice] uniqueIdentifier]

What SHOULD we be using instead?

What if the phone is sold to another user... and an app has stored some data on a remote server, based on the phone's UDID?

(Of course, I want to avoid the problems with the app store's "encryption restrictions".)


Why not use the Mac Address and possibly then hash it up.

There is an excellent UIDevice-Extension Category here

    - (NSString *) macaddress
{
    int                 mib[6];
    size_t              len;
    char                *buf;
    unsigned char       *ptr;
    struct if_msghdr    *ifm;
    struct sockaddr_dl  *sdl;

    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;

    if ((mib[5] = if_nametoindex("en0")) == 0) {
        printf("Error: if_nametoindex error\n");
        return NULL;
    }

    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 1\n");
        return NULL;
    }

    if ((buf = malloc(len)) == NULL) {
        printf("Could not allocate memory. error!\n");
        return NULL;
    }

    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 2");
        return NULL;
    }

    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", 
                           *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
    // NSString *outstring = [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X", 
    //                       *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
    free(buf);

    return outstring;
}

You could possibly hash this with the model?


As I asked this morning in this post, there are some alternative :

1- first, as Apple recommands, identify per install instead of indentifying per device. Therefore, you can use CFUUIDRef. Example :

NSString *uuid = nil;
CFUUIDRef theUUID = CFUUIDCreate(kCFAllocatorDefault);
if (theUUID) {
  uuid = NSMakeCollectable(CFUUIDCreateString(kCFAllocatorDefault, theUUID));
  [uuid autorelease];
  CFRelease(theUUID);
}

2- If you care about a worldwide unique identifier, so you could store this identifier on iCloud.

3- At last, if you really need an identifier that remains after app re-install (that not occurs so frequently), you can use Keychains (Apple's keychain doc). But will apple team like it ?


UUID is just depreciated and so will be around for a while, Apple have not said much about this depreciation much yet, I would wait until they have more to say about this and maybe the will offer some alternative.


Like this:

@interface UIDevice (UIDeviceAppIdentifier)
@property (readonly) NSString *deviceApplicationIdentifier;
@end

@implementation UIDevice (UIDeviceAppIdentifier)
- (NSString *) deviceApplicationIdentifier
{ 
  static NSString     *name    = @"theDeviceApplicationIdentifier";
  NSUserDefaults  *defaults = [NSUserDefaults standardUserDefaults];  
  NSString              *value     = [defaults objectForKey: name];

  if (!value)
    {
      value = (NSString *) CFUUIDCreateString (NULL, CFUUIDCreate(NULL));    
      [defaults setObject: value forKey: name];
      [defaults synchronize];
  }
  return value;
}
@end

the iOS documentation more or less describes use of CFUUIDCreate() to create an identifier and suggests using UserDefaults to store it.


The recommended way is by using UUID generation, and associate that with something that the user him/herself is willing to provide to the app.

Then, store this data externally, where it could be retrieved again. There are probably other ways to do this easily, but this is the recommended way.


One solution would be to have the application issue a free in-app purchase.

This purchase would be:

  1. Trackable, with a unique number (purchase) number which would be meaningful only to your app.

  2. Movable, if the person switches devices

  3. Retrievable, if the app is deleted (or the phone is wiped and reloaded) - the In-App purchases can be restored.


Apple's documentation says:

"Do not use the uniqueIdentifier property. To create a unique identifier specific to your app, you can call the CFUUIDCreate function to create a UUID, and write it to the defaults database using the NSUserDefaults class."

Here's a quick snippet:

CFUUIDRef udid = CFUUIDCreate(NULL);

NSString *udidString = (NSString *) CFUUIDCreateString(NULL, udid);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜