如何使用Objective-c为iPhone/iPad生成设备唯一标识符

11

我想知道如何使用Objective-c为iPhone/iPad生成设备唯一标识符,以便在应用安装到设备上后我们可以跟踪该设备的ID。

  • 我尝试查找检索iPhone/iPad的IMEI,但这在Objective-c中是不允许的。

  • 然后我尝试生成iPhone/iPad的UDID,但每次在模拟器上启动时它都会生成不同的ID。


请参考这个答案:http://stackoverflow.com/a/39992564/6656894 - Himanshu Moradiya
7个回答

21

是的,UDID已经被弃用;由于用户隐私目的,我们不允许获取UDID。苹果不允许获取任何可以唯一标识设备的标识符,例如IMEI、MAC地址、UDID等。

UUID是目前最好的选择。但每个供应商的UUID都是唯一的,不能保证每次获取UUID字符串时它都是唯一的。最好的方法是将UUID字符串存储到手机的Keychain中,并在需要时检索它,但有一个限制。当您对手机进行出厂设置时,Keychain项目会被删除。需要记住这个限制。


更新-IOS 10.3测试版:

看起来苹果对iOS 10.3+中Keychain的工作方式做了一些更改。在卸载指定供应商的所有应用程序后,存储在Keychain中的Keychain项目将被删除。据苹果称,即使应用程序从设备中消失,应用程序的敏感信息仍然存在可能存在安全风险,因此他们禁止这种行为。

依赖Keychain存储甚至在卸载应用程序后继续使用的开发人员可以使用这个解决方法继续使用预期的功能。根据这个解决方法,任何应用程序都可以访问存储在特定Keychain访问组中的信息,因此建议为您的数据添加额外的加密层,以获得更高的安全性,尽管Keychain默认情况下对项目进行加密。


更新-IOS 10.3.3(稳定版):

似乎在 iOS 10.3.3 的早期测试版本中,钥匙串项目的删除是一个 BUG,在稳定版本中得到了修复。这可能是由于测试期间出现了一些奇怪的事情导致的。之后使用钥匙串应该没有问题。


2
那是在10.3测试版中的一个错误,卸载应用程序会删除其钥匙串数据,但现在不是这种情况了。请参见此处 - Mohammad Zaid Pathan
@ZaidKhan 是的,我看到了那篇帖子。是否有任何官方确认或文档说明那已经正常工作了?我会更新我的答案。但是不能百分之百确定它或开发者论坛。 - badhanganesh
@BadhanGanesh 我认为没有任何官方文档显示10.3会删除Keychain数据,所以你要求的文档是不存在的。不是吗? - Mohammad Zaid Pathan
是的。毕竟这个 bug 是由开发人员发现的。我猜目前还没有任何发布说明中官方的消息提到这个 bug。我认为这个问题不会在未来继续存在,这应该是安全的。 - badhanganesh
现在在iOS 11中的状态是什么?另外,我想知道使用相同的Apple ID是否可以将钥匙串同步到所有设备上? - abhimuralidharan

13

你可以使用UUID(通用唯一标识符)。以下链接包含苹果文档:

https://developer.apple.com/reference/uikit/uidevice/1620059-identifierforvendor

https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS7.html#//apple_ref/doc/uid/TP40013162-SW1

你可以使用以下代码获取UUID:

//Objective-C

NSString * string =  [[[UIDevice currentDevice] identifierForVendor] UUIDString];

//Swift

->

//Swift

let deviceID = UIDevice.currentDevice().identifierForVendor?.UUIDString 

//Swift 3

->

//Swift 3

let deviceID = UIDevice.current.identifierForVendor?.uuidString

1
这对设备来说是唯一的吗?如果我删除一个应用程序然后重新安装它,它会是相同的吗? - Zeeshan
3
不,它不会保持原样。当您删除并重新安装时,它会生成一个新的。 - Asaduzzaman Shuvro

6

使用以下代码获取iOS设备的UDID: 使用从URL下载的KeychainItemWrapper类 KeychainItemWrap

NSString *uuid;
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"AC_APP_UUID" accessGroup:nil];
NSString *keychainUUID = [keychain objectForKey:(__bridge id)(kSecAttrAccount)];
NSString *appVersion = [NSString stringWithFormat:@"%@",@"1.0"];
[keychain setObject:appVersion forKey:(__bridge id)(kSecAttrDescription)];
if (keychainUUID==nil||[keychainUUID isKindOfClass:[NSNull class]]||keychainUUID.length==0) {
    uuid = [[NSUUID UUID] UUIDString];
    [keychain setObject:uuid forKey:(__bridge id)(kSecAttrAccount)];
}else{
    uuid = [keychain objectForKey:(__bridge id)(kSecAttrAccount)];
}

2

如果您是2017年之后发布的应用,苹果已经实施了DeviceCheck功能。

https://developer.apple.com/documentation/devicecheck#overview

您可以使用DeviceCheck来查看此特定设备是否安装或使用过您的特定应用程序。它不会为手机提供唯一的ID,但它确实允许您查看用户是否已经使用完了促销活动。


-1

您无法获取用户手机的IMEI和电话号码,苹果公司限制了获取这些uniqueID的权限。

您必须将UDID存储在钥匙串中。为此,您需要下载keychainwrapper类并存储由上述代码生成的UDID:

   UIDevice *device = [[UIDevice alloc]init]; 
   NSString *idForVend = [NSString stringWithFormat:@"%@", [device identifierForVendor]]; 
   NSLog(@"Identifier For Vendor : %@",idForVend);

请点击此链接,它一定会解决你的问题:https://stackoverflow.com/questions/16459879/how-to-store-a-string-in-keychain-ios,iOS? 如果您使用这个方法,即使您删除应用程序并重新安装,设备ID也将保持不变。


-2
#import <AdSupport/AdSupport.h>

NSString* sClientID = [[[ASIdentifierManager sharedManager]advertisingIdentifier] UUIDString];

最好的UUID,因为:
  1. 它永远不会改变(即使应用程序被删除)
  2. 苹果公司批准它。

1
错误。文档中说advertisingIdentifier"可能会改变——例如,如果用户擦除设备"。我认为也可以通过转到“设置”>“隐私”>“广告”>“重置广告标识符”来更改它。此外,"在iOS 10.0及更高版本中,当用户限制广告跟踪时,advertisingIdentifier的值为全零",因此它不是唯一的。 - Pang
@Pang,你有解决方案吗? - Ofir Malachi
@Pang 我也需要解决方案。 - SANTOSH

-6
解决方案是:
您可以使用DeviceToken来完成。DeviceToken对于所有移动设备都是唯一的。
代码在这里:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)])
    {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];

        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    else
    {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
    }
    return yes;

}


- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{

   NSString *AppDeviceToken=[[NSString alloc] initWithFormat:@"%@",deviceToken];
    //NSLog(@"My token is: %@", self.AppDeviceToken);

   AppDeviceToken = [self.AppDeviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];
   AppDeviceToken = [self.AppDeviceToken stringByReplacingOccurrencesOfString:@"<" withString:@""];
   AppDeviceToken = [self.AppDeviceToken stringByReplacingOccurrencesOfString:@">" withString:@""];

    NSLog(@"%@'s Device Token is : %@",[[UIDevice currentDevice] name],AppDeviceToken);
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
    NSLog(@"Failed to get token, error: %@", error);
}

设备令牌对于所有设备都是唯一的。


1
设备ID可以改变,如果您删除应用程序并在同一设备上重新安装。 - Wolverine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接