簡體   English   中英

卸載設備上的ios應用后,如何在ios中保留identifierForVendor?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM