刚刚发现,UIDevice uniqueIdentifier属性在iOS 5中已弃用,在iOS 7及以上版本中不可用。似乎没有可供选择的方法或属性。
我们现有的许多应用程序都紧密依赖于这个属性来唯一地识别特定的设备。今后我们该如何处理这个问题?
2011-2012年的文件建议:
特殊注意事项
不要使用uniqueIdentifier属性。创建特定的唯一标识符
你可以调用CFUUIDCreate函数来创建一个UUID,然后写入
使用NSUserDefaults类将它转换到默认数据库。
但是,如果用户卸载和重新安装应用程序,这个值就不一样了。
我相信苹果公司的这一变化惹恼了很多人。我开发了一个iOS的簿记应用程序,并有一个在线服务来同步不同设备上的更改。该服务维护所有设备的数据库以及需要传播到这些设备的更改。因此,了解哪种设备是哪种设备很重要。我使用UIDevice uniqueIdentifier跟踪设备,为了它的价值,这里是我的想法。
Generate a UUID and store in user defaults?
No good because this does not persist when the user deletes the app. If they install again later the online service should not create a new device record, that would waste resources on the server and give a list of devices containing the same one two or more times. Users would see more than one "Bob's iPhone" listed if they re-installed the app.
Generate a UUID and store in the keychain?
This was my plan, since it persists even when the app is uninstalled. But when restoring an iTunes backup to a new iOS device, the keychain is transferred if the backup is encrypted. This could lead to two devices containing the same device id if the old and new devices are both in service. These should be listed as two devices in the online service, even if the device name is the same.
Generate a hash the MAC address and bundle id?
This looks like the best solution for what I need. By hashing with the bundle id, the generated device id is not going to enable the device to be tracked across apps and I get a unique ID for the app+device combination.
有趣的是,苹果自己的文档提到通过计算系统Mac地址加上bundle id和版本的哈希来验证Mac App Store收据。所以这似乎是政策允许的,但是否通过应用审查我还不知道。
虽然不完美,但却是UDID的最佳和最接近的替代品之一(在Swift中使用iOS 8.1和Xcode 6.1):
生成一个随机UUID
let strUUID: String = NSUUID().UUIDString
并使用KeychainWrapper库:
给keychain添加一个字符串值:
let saveSuccessful: Bool = KeychainWrapper.setString("Some String", forKey: "myKey")
从keychain中检索字符串值:
let retrievedString: String? = KeychainWrapper.stringForKey("myKey")
从keychain中删除一个字符串值:
let removeSuccessful: Bool = KeychainWrapper.removeObjectForKey("myKey")
该解决方案使用了keychain,因此存储在keychain中的记录将被持久化,即使在应用程序卸载和重新安装之后。删除该记录的唯一方法是重置设备的所有内容和设置。这就是为什么我提到这个替代方案并不完美,但仍然是iOS 8.1上使用Swift替代UDID的最佳方案之一。