![](/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.