在设备上卸载 ios 应用程序后,如何在 ios 中保留 identifierForVendor?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21878560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:29:41  来源:igfitidea点击:

How to preserve identifierForVendor in ios after uninstalling ios app on device?

iosuuiduniqueidentifieridentifier

提问by Harshavardhan

I am developing an iOS app which calls web-service for login and at that time i send login credentials to web server along with vendor identifier (identifierForVendor),to identify device uniquely for those credentials.So user can have only one device and one credential.

我正在开发一个 iOS 应用程序,它调用 Web 服务进行登录,当时我将登录凭据与供应商标识符 (identifierForVendor) 一起发送到 Web 服务器,以便为这些凭据唯一标识设备。因此用户只能拥有一台设备和一个凭据.

I got identifierForVendor with

我得到了 identifierForVendor

NSString *uuid = [[UIDevice currentDevice] identifierForVendor].UUIDString

This identifier will then store in database of web server and also in device database.Next time when user opens application and will try to download data from web server firstly local identifierForVendor on users device will compare with identifier stored on web server.

然后这个标识符将存储在网络服务器的数据库和设备数据库中。下次当用户打开应用程序并尝试从网络服务器下载数据时,用户设备上的本地标识符ForVendor 将与存储在网络服务器上的标识符进行比较。

Problem occurs when user uninstall app and reinstall it, I found that identifierForVendor is changed. So user cannot proceed further.

用户卸载应用程序并重新安装时出现问题,我发现 identifierForVendor 已更改。所以用户不能继续。

I read apple documentation UIDevice Documentation

我阅读了苹果文档UIDevice 文档

As mention there, if all app from same vendor uninstalls from device then at time of new installation of any app from that vendor will take new identifierForVendor.

如上所述,如果来自同一供应商的所有应用程序都从设备上卸载,那么在新安装来自该供应商的任何应用程序时,将采用新的 identifierForVendor。

So how to deal with this in my case ?

那么在我的情况下如何处理呢?

采纳答案by nerowolfe

You may keep it in KeyChain

您可以将其保存在 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;
}

回答by Wain

Generally, don't use identifierForVendor. Instead, use NSUUIDto generate a custom UUID and store that in the keychain (because the keychain isn't deleted if the app is deleted and reinstalled).

一般不要使用identifierForVendor。相反,用于NSUUID生成自定义 UUID 并将其存储在钥匙串中(因为如果删除并重新安装应用程序,钥匙串不会被删除)。

回答by griga13

Addition to @nerowolfe's answer.

除了@nerowolfe 的回答

SSKeychainuses kSecAttrSynchronizableAnyas a default synchronization mode. You probably don't want identifierForVendorto be synced across multiple devices so here is a code:

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];

回答by iphonic

You can try use KeyChainto save your VendorIdentifier, that will exist till your device is reset, even if you uninstall your app.

您可以尝试使用KeyChain来保存您的VendorIdentifier,它会一直存在,直到您的设备被重置,即使您卸载了您的应用程序。

回答by Michael Kalinin

Swift version

迅捷版

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
}

回答by Gautam Jain

Ok. I didn't want to use a third party - namely SSKeychain. So this is the code I tried, fairly simple and works well:

好的。我不想使用第三方 - 即 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)]);
}

回答by rckoenes

There is no definite way to link a unique number to a device any more, this is not allowed with the Apple privacy guidelines.

没有明确的方法可以将唯一号码链接到设备,这是 Apple 隐私准则所不允许的。

You can try to save your own Unique ID in the keychain, but if the user clear his device this ID is also gone.

您可以尝试将自己的唯一 ID 保存在钥匙串中,但如果用户清除其设备,该 ID 也会消失。

Generally is it just wrong to link a device to a user, since you are not longer identifying users but devices. So you should just change your API so that the user can re-login and that the vendor ID is bound to the users account.

通常将设备链接到用户是错误的,因为您不再识别用户而是设备。因此,您应该更改您的 API,以便用户可以重新登录并将供应商 ID 绑定到用户帐户。

Also what happens when the user has more then one device, like an iPhone and iPad, and uses you app on both? Since you authentication is based an unique ID this can not be done.

另外,当用户拥有不止一个设备(例如 iPhone 和 iPad)并且在这两个设备上都使用您的应用程序时会发生什么?由于您的身份验证基于唯一 ID,因此无法完成。

回答by Jayprakash Dubey

I had used KeychainAccesspod for this problem.

我曾使用KeychainAccesspod 来解决这个问题。

In your pod file :

在您的 pod 文件中:

pod 'KeychainAccess', '~> 2.4' //If you are using Swift 2.3 
pod 'KeychainAccess' //Defaults to 3.0.1 which is in Swift 3

Import KeychainAccessmodule in file where you want to set UUID in keychain

KeychainAccess在要在钥匙串中设置 UUID 的文件中导入模块

import KeychainAccess

Use below code to set and get UUID from keychain :

使用以下代码从钥匙串设置和获取 UUID:

Note :BundleId is key and UUID is value

注意: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
    }