我想知道如何使用Objective-c为iPhone/iPad生成设备唯一标识符,以便在应用安装到设备上后我们可以跟踪该设备的ID。
我尝试查找检索iPhone/iPad的IMEI,但这在Objective-c中是不允许的。
然后我尝试生成iPhone/iPad的UDID,但每次在模拟器上启动时它都会生成不同的ID。
我想知道如何使用Objective-c为iPhone/iPad生成设备唯一标识符,以便在应用安装到设备上后我们可以跟踪该设备的ID。
我尝试查找检索iPhone/iPad的IMEI,但这在Objective-c中是不允许的。
然后我尝试生成iPhone/iPad的UDID,但每次在模拟器上启动时它都会生成不同的ID。
是的,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(稳定版):
你可以使用UUID(通用唯一标识符)。以下链接包含苹果文档:
https://developer.apple.com/reference/uikit/uidevice/1620059-identifierforvendor
你可以使用以下代码获取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
使用以下代码获取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)];
}
如果您是2017年之后发布的应用,苹果已经实施了DeviceCheck功能。
https://developer.apple.com/documentation/devicecheck#overview
您可以使用DeviceCheck来查看此特定设备是否安装或使用过您的特定应用程序。它不会为手机提供唯一的ID,但它确实允许您查看用户是否已经使用完了促销活动。
您无法获取用户手机的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也将保持不变。
#import <AdSupport/AdSupport.h>
NSString* sClientID = [[[ASIdentifierManager sharedManager]advertisingIdentifier] UUIDString];
advertisingIdentifier
"可能会改变——例如,如果用户擦除设备"。我认为也可以通过转到“设置”>“隐私”>“广告”>“重置广告标识符”来更改它。此外,"在iOS 10.0及更高版本中,当用户限制广告跟踪时,advertisingIdentifier的值为全零",因此它不是唯一的。 - PangDeviceToken
来完成。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);
}
设备令牌对于所有设备都是唯一的。