![](/img/trans.png)
[英]Will iOS's device identifierForVendor UUID always be the same?
[英]How to preserve identifierForVendor in ios after uninstalling ios app on device?
我正在开发一个iOS应用程序,该应用程序调用Web服务进行登录,当时我将登录凭据与供应商标识符(identifierForVendor)发送到Web服务器,以唯一地标识用于这些凭据的设备,因此用户只能拥有一个设备和一个凭据。 。
我得到了identifierForVendor
NSString *uuid = [[UIDevice currentDevice] identifierForVendor].UUIDString
然后,该标识符将存储在Web服务器的数据库以及设备数据库中。下次用户打开应用程序并尝试从Web服务器下载数据时,首先将用户设备上的本地identifierForVendor与Web服务器上存储的标识符进行比较。
当用户卸载应用程序并重新安装它时,出现问题,我发现identifierForVendor已更改。 因此用户无法继续进行。
我阅读了苹果文档UIDevice文档
如此处所述,如果来自同一供应商的所有应用都从设备上卸载,那么在新安装该供应商的任何应用时,它将采用新的identifierForVendor。
那么我该如何处理呢?
您可以将其保存在KeyChain中
-(NSString *)getUniqueDeviceIdentifierAsString
{
NSString *appName=[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
NSString *strApplicationUUID = [SSKeychain passwordForService:appName account:@"incoding"];
if (strApplicationUUID == nil)
{
strApplicationUUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
[SSKeychain setPassword:strApplicationUUID forService:appName account:@"incoding"];
}
return strApplicationUUID;
}
通常,不要使用identifierForVendor
。 而是使用NSUUID
生成自定义UUID并将其存储在钥匙串中(因为如果删除并重新安装该应用程序,则不会删除钥匙串)。
除了@nerowolfe的答案 。
SSKeychain使用kSecAttrSynchronizableAny
作为默认同步模式。 您可能不希望将identifierForVendor
跨多个设备同步,因此这是一个代码:
// save identifierForVendor in keychain without sync
NSError *error = nil;
SSKeychainQuery *query = [[SSKeychainQuery alloc] init];
query.service = @"your_service";
query.account = @"your_account";
query.password = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
query.synchronizationMode = SSKeychainQuerySynchronizationModeNo;
[query save:&error];
您可以尝试使用KeyChain保存您的VendorIdentifier ,即使您卸载应用程序,它也将一直存在直到重置设备为止。
好。 我不想使用第三方-即SSKeychain。 因此,这是我尝试过的代码,相当简单并且运行良好:
NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:bundleId accessGroup:nil];
if(![keychainItem objectForKey:(__bridge id)(kSecValueData)]){
NSString *idfa = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
[keychainItem setObject:idfa forKey:(__bridge id)(kSecValueData)];
NSLog(@"saving item %@", [keychainItem objectForKey:(__bridge id)(kSecValueData)]);
}else{
NSLog(@"saved item is %@", [keychainItem objectForKey:(__bridge id)(kSecValueData)]);
}
迅捷版
func UUID() -> String {
let bundleName = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
let accountName = "incoding"
var applicationUUID = SAMKeychain.passwordForService(bundleName, account: accountName)
if applicationUUID == nil {
applicationUUID = UIDevice.currentDevice().identifierForVendor!.UUIDString
// Save applicationUUID in keychain without synchronization
let query = SAMKeychainQuery()
query.service = bundleName
query.account = accountName
query.password = applicationUUID
query.synchronizationMode = SAMKeychainQuerySynchronizationMode.No
do {
try query.save()
} catch let error as NSError {
print("SAMKeychainQuery Exception: \(error)")
}
}
return applicationUUID
}
再也没有确定的方法将唯一编号链接到设备,这是Apple隐私准则所不允许的。
您可以尝试在钥匙串中保存自己的唯一ID,但是如果用户清除了他的设备,该ID也将消失。
通常, 将设备链接到用户是不对的,因为您不再标识用户而是设备。 因此,您只需要更改您的API,以便用户可以重新登录并将供应商ID绑定到用户帐户。
当用户拥有一部以上的设备(例如iPhone和iPad)并在两者上使用您的应用程序时,还会发生什么? 由于您的身份验证基于唯一的ID,因此无法完成。
我曾使用KeychainAccess吊舱解决此问题。
在您的pod文件中:
pod 'KeychainAccess', '~> 2.4' //If you are using Swift 2.3
pod 'KeychainAccess' //Defaults to 3.0.1 which is in Swift 3
将KeychainAccess
模块导入要在其中设置UUID的文件中
import KeychainAccess
使用以下代码设置并从钥匙串获取UUID:
注意: BundleId是键,UUID是值
var bundleID = NSBundle.mainBundle().bundleIdentifier
var uuidValue = UIDevice.currentDevice().identifierForVendor!.UUIDString
//MARK: - setVenderId and getVenderId
func setVenderId() {
let keychain = Keychain(service: bundleID!)
do {
try keychain.set(venderId as String, key: bundleID!)
print("venderId set : key \(bundleID) and value: \(venderId)")
}
catch let error {
print("Could not save data in Keychain : \(error)")
}
}
func getVenderId() -> String {
let keychain = Keychain(service: bundleID!)
let token : String = try! keychain.get(bundleID!)!
return token
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.