哇...这一周在线上有很多关于使用iPhone的UDID的“恐慌故事”。
涉及到技术方面,请您谅解,如有不当之处请指出。 [[UIDevice currentDevice] uniqueIdentifier]
我们应该使用什么替代品?
如果手机被卖给另一个用户......并且一个应用程序基于手机的UDID在远程服务器上存储了一些数据,那该怎么办?
(当然,我想避免应用商店的“加密限制”问题。)
哇...这一周在线上有很多关于使用iPhone的UDID的“恐慌故事”。
涉及到技术方面,请您谅解,如有不当之处请指出。 [[UIDevice currentDevice] uniqueIdentifier]
我们应该使用什么替代品?
如果手机被卖给另一个用户......并且一个应用程序基于手机的UDID在远程服务器上存储了一些数据,那该怎么办?
(当然,我想避免应用商店的“加密限制”问题。)
为什么不使用Mac地址,然后将其哈希化。
这里有一个优秀的UIDevice-Extension类别在这里。
- (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;
}
正如我在今天早上在这篇文章中提出的问题,有一些替代方案:
1- 首先,像Apple推荐的那样,按安装进行识别而不是按设备进行识别。 因此,您可以使用CFUUIDRef。例如:
NSString *uuid = nil;
CFUUIDRef theUUID = CFUUIDCreate(kCFAllocatorDefault);
if (theUUID) {
uuid = NSMakeCollectable(CFUUIDCreateString(kCFAllocatorDefault, theUUID));
[uuid autorelease];
CFRelease(theUUID);
}
2- 如果您关心一个全球唯一标识符,那么您可以将此标识符存储在iCloud上。
3- 最后,如果您真的需要一个在应用程序重新安装后仍然存在的标识符(这并不经常发生),您可以使用Keychains(苹果的keychain文档)。 但是,苹果团队会喜欢吗?
像这样:
@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
iOS文档或多或少地描述了使用CFUUIDCreate()来创建标识符,并建议使用UserDefaults来存储它。
UUID 已经被弃用,但它仍将存在一段时间。苹果公司尚未对此进行太多说明,我建议等待他们有更多的说法,或许他们会提供一些替代方案。
苹果的文档说:
“不要使用uniqueIdentifier属性。为了创建一个特定于您的应用程序的唯一标识符,您可以调用CFUUIDCreate函数来创建一个UUID,并使用NSUserDefaults类将其写入默认数据库。”
这是一个快速的代码片段:
CFUUIDRef udid = CFUUIDCreate(NULL);
NSString *udidString = (NSString *) CFUUIDCreateString(NULL, udid);
推荐的方法是使用UUID生成,并将其与用户自己愿意提供给应用程序的内容相关联。
然后,将这些数据存储在外部,以便可以再次检索。可能有其他更容易的方法来实现这一点,但这是推荐的方法。
一个解决方案是让应用程序发出免费的应用内购买。
这个购买将会是:
可追踪的,具有唯一的编号(购买)号码,仅对您的应用程序有意义。
可移动的,如果用户更换设备
可检索的,如果应用程序被删除(或手机被擦除和重新加载)- 应用内购买可以被恢复。