【Swift 开发】IDFA存储到钥匙串中保证永久不变,除非系统重装

一、 IDFA值会发生改变的情况

在何种情况下 , 应用的IDFA值会发生改变?

在iOS的设置应用中选择“重置所有设置”
*没有影响

在iOS的设置应用中“清除所有的内容和设置”
*advertisingIdentifier 和 identifierForVendor 都会受到影响重新设置变为新值

通过iTunes还原设备
*advertisingIdentifier 和 identifierForVendor 都会受到影响重新设置变为新值

从设备上删除该APP
*如果该APP是某个开发者账号下在该设备上的最后一个APP时,会影响identifierForVendor 的值,否则不会影响该字段的值。

升级应用
*无影响

启用或关闭“限制广告追踪”
*应影响advertisingIdentifier 字段的具体值

系统升级(通过手机自己升级或通过iTunes升级)
*会改变identifierForVendor 字段的值

在iOS的设置应用中“重新设置广告标示符”
*会改变advertisingIdentifier 的值。如果一些应用正在请求该字段,那么在该应用重新启动前该字段的值并不会发生改变。

通过iTunes进行备份
*对这两个字段没有影响

通过iTunes对备份进行还原
*两个字段都会被重置

二、如何保证IDFA不变

将IDFA存到系统的钥匙串里面

//  系统钥匙串管理工具类


import UIKit

class BCSKeyChainTool: NSObject {
    /// 查询
    static func getKeychainQuery(service: String) -> NSMutableDictionary {
        return NSMutableDictionary.init(objects: [kSecClassGenericPassword, service, service, kSecAttrAccessibleAfterFirstUnlock], forKeys: [kSecClass as! NSCopying, kSecAttrService as! NSCopying, kSecAttrAccount as! NSCopying, kSecAttrAccessible as! NSCopying])
    }
    /// 保存
    static func save(service: String, data: Any) {
        // Get search dictionary
        let keychainQuery = self.getKeychainQuery(service: service)
        // Delete old item before add new item
        SecItemDelete(keychainQuery)
        // Add new object to search dictionary(Attention:the data format)
        keychainQuery.setObject(NSKeyedArchiver.archivedData(withRootObject: data), forKey: kSecValueData as! NSCopying)
        // Add item to keychain with the search dictionary
        SecItemAdd(keychainQuery, nil)
    }

    /// 加载
    static func load(service: String) -> String {
        var ret: String = ""
        let keychainQuery = self.getKeychainQuery(service: service)
        // Configure the search setting
        // Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue
        keychainQuery.setObject(kCFBooleanTrue, forKey: kSecReturnData as! NSCopying)
        keychainQuery.setObject(kSecMatchLimitOne, forKey: kSecMatchLimit as! NSCopying)
        var keyData: CFTypeRef?
        if SecItemCopyMatching(keychainQuery, &keyData) == noErr {
            ret = NSKeyedUnarchiver.unarchiveObject(with: keyData as! Data) as! String
        }
        return ret
    }
    
    /// 删除
    static func deleteKeyData(service: String) {
        let keychainQuery = self.getKeychainQuery(service: service)
        SecItemDelete(keychainQuery)
    }
    
}


转载出处

其实和 OC 的SAMKeychain的作用是一样的

你可能感兴趣的:(【Swift 开发】IDFA存储到钥匙串中保证永久不变,除非系统重装)