ios 不推荐使用 UIDevice uniqueIdentifier - 现在该怎么办?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6993325/
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 21:01:29  来源:igfitidea点击:

UIDevice uniqueIdentifier deprecated - What to do now?

iosdeprecateduidevice

提问by Oliver Pearmain

It has just come to light that the UIDevice uniqueIdentifier property is deprecatedin iOS 5and unavailable in iOS 7 and above. No alternative method or property appears to be available or forthcoming.

刚刚发现UIDevice uniqueIdentifier 属性iOS 5 中已弃用,在 iOS 7 及更高版本中不可用。似乎没有可用或即将出现的替代方法或属性。

Many of our existing apps are tightly dependent on this property for uniquely identifying a particular device. How might we handle this problem going forward?

我们现有的许多应用程序都紧密依赖此属性来唯一标识特定设备。我们将如何处理这个问题?

The suggestion from the documentation in 2011-2012was:

2011-2012文档中的建议是:

Special Considerations

Do not use the uniqueIdentifier property. To create a unique identifier specific to your app, you can call the CFUUIDCreatefunction to create a UUID, and write it to the defaults database using the NSUserDefaultsclass.

特别注意事项

不要使用 uniqueIdentifier 属性。要创建特定于您的应用程序的唯一标识符,您可以调用该CFUUIDCreate函数来创建一个UUID,然后使用NSUserDefaults该类将其写入默认数据库。

However this value won't be the same if a user uninstalls and re-installs the app.

但是,如果用户卸载并重新安装应用程序,则此值将不同。

采纳答案by DarkDust

A UUID created by CFUUIDCreateisunique if a user uninstalls and re-installs the app: you will get a new one each time.

如果用户卸载并重新安装应用程序,CFUUIDCreate创建的 UUID唯一的:您每次都会得到一个新的。

But you might want it to be notunique, i. e. it should stay the same when the user uninstalls and re-installs the app. This requires a bit of effort, since the most reliable per-device-identifier seems to be the MAC address. You could query the MACand use that as UUID.

但是您可能希望它不是唯一的,即当用户卸载并重新安装应用程序时它应该保持不变。这需要一些努力,因为最可靠的每设备标识符似乎是 MAC 地址。您可以查询 MAC并将其用作 UUID。

Edit:One needs to always query the MAC of the same interface, of course. I guess the best bet is with en0. The MAC is always present, even if the interface has no IP/is down.

编辑:当然,需要始终查询同一接口的 MAC。我想最好的选择是使用en0. MAC 始终存在,即使接口没有 IP/已关闭。

Edit 2:As was pointed out by others, the preferred solution since iOS 6 is -[UIDevice identifierForVendor]. In most cases, you should be able use it as a drop-in replacement to the old -[UIDevice uniqueIdentifier](but a UUID that is created when the app starts for the first time is what Apple seems to want you to use).

编辑 2:正如其他人所指出的,自 iOS 6 以来的首选解决方案是-[UIDevice identifierForVendor]。在大多数情况下,您应该可以将其用作旧版本的替代品-[UIDevice uniqueIdentifier](但在应用程序首次启动时创建的 UUID 似乎是 Apple 希望您使用的)。

Edit 3:So this major point doesn't get lost in the comment noise: do not use the MACas UUID, create a hash using the MAC. That hash will always create the same result every time, even across reinstalls and apps (if the hashing is done in the same way). Anyways, nowadays (2013) this isn't necessary any more except if you need a "stable" device identifier on iOS < 6.0.

编辑 3:所以这个主要观点不会在评论噪音中迷失:不要使用MAC作为 UUID,使用 MAC创建哈希。即使在重新安装和应用程序之间(如果散列以相同的方式完成),该散列每次将始终创建相同的结果。无论如何,如今(2013 年)这不再需要,除非您需要 iOS < 6.0 上的“稳定”设备标识符。

Edit 4:In iOS 7, Apple now always returns a fixed value when querying the MAC to specifically thwart the MAC as base for an IDscheme. So you now really should use -[UIDevice identifierForVendor]or create a per-install UUID.

编辑 4:在 iOS 7 中,Apple 现在在查询 MAC 时总是返回一个固定值,以专门阻止MAC 作为 ID方案的基础。所以你现在真的应该使用-[UIDevice identifierForVendor]或创建一个 per-install UUID。

回答by Serhii Mamontov

You can use your alternative for Apple UDIDalready. Kind guy gekitz wrote category on UIDevicewhich will generate some kind of UDIDbased on device mac-address and bundle identifier.

UDID已经可以使用 Apple 的替代品了。好心人 gekitz 编写了类别UIDevice,将UDID根据设备 mac 地址和捆绑标识符生成某种类别。

You can find code on github

你可以在github上找到代码

回答by Mat

Based on the link proposed by @moonlight, i did several tests and it seems to be the best solution. As @DarkDust says the method goes to check en0which is always available.
There are 2 options:
uniqueDeviceIdentifier(MD5 of MAC+CFBundleIdentifier)
and uniqueGlobalDeviceIdentifier(MD5 of the MAC), these always returns the same values.
Below the tests i've done (with the real device):

根据@moonlight 提出的链接,我做了几次测试,这似乎是最好的解决方案。正如@DarkDust 所说,该方法会检查en0哪个始终可用。
有 2 个选项:
uniqueDeviceIdentifier(MAC+CFBundleIdentifier 的MD5 )
uniqueGlobalDeviceIdentifier(MAC 的 MD5),它们总是返回相同的值。
在我完成的测试下面(使用真实设备):

#import "UIDevice+IdentifierAddition.h"

NSLog(@"%@",[[UIDevice currentDevice] uniqueDeviceIdentifier]);
NSLog(@"%@",[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]);

XXXX21f1f19edff198e2a2356bf4XXXX - (WIFI)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (WIFI)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (3G)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (3G)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (GPRS)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (GPRS)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (AirPlane mode)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (AirPlane mode)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (Wi-Fi)after removing and reinstalling the app XXXX7dc3c577446a2bcbd77935bdXXXX (Wi-Fi) after removing and installing the app

XXXX21f1f19edff198e2a2356bf4XXXX - (WIFI)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (WIFI)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (3G)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (3G)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (GPRS)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (GPRS)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX -(飞行模式)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX -(飞行模式)GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (Wi-Fi) 移除并重新安装应用程序后 XXXX7dc3c577446a2bcbd77935bdXXXX (Wi-Fi) 移除和安装应用程序后

Hope it's useful.

希望它有用。

EDIT:
As others pointed out, this solution in iOS 7 is no longer useful since uniqueIdentifieris no longer available and querying for MAC address now returns always 02:00:00:00:00:00

编辑:
正如其他人指出的那样,iOS 7 中的此解决方案不再有用,因为uniqueIdentifier不再可用并且查询 MAC 地址现在总是返回 02:00:00:00:00:00

回答by ytur

check this out,

看一下这个,

we can use Keychain instead of NSUserDefaultsclass, to store UUIDcreated by CFUUIDCreate.

我们可以使用 Keychain 而不是NSUserDefaultsclass,来存储UUIDCFUUIDCreate.

with this way we could avoid for UUIDrecreation with reinstallation, and obtain always same UUIDfor same application even user uninstall and reinstall again.

通过这种方式,我们可以避免UUID通过重新安装进行娱乐,并且UUID即使用户卸载并再次重新安装,对于相同的应用程序也始终相同。

UUIDwill recreated just when device reset by user.

UUID将在用户重置设备时重新创建。

I tried this method with SFHFKeychainUtilsand it's works like a charm.

我用SFHFKeychainUtils尝试了这种方法,它的作用就像一个魅力。

回答by Samir Jwarchan

Create your own UUID and then store it in the Keychain. Thus it persists even when your app gets uninstalled. In many cases it also persists even if the user migrates between devices (e.g. full backup and restore to another device).

创建您自己的 UUID,然后将其存储在钥匙串中。因此,即使您的应用程序被卸载,它仍然存在。在许多情况下,即使用户在设备之间迁移(例如完全备份和恢复到另一台设备),它也会持续存在。

Effectively it becomes a unique user identifieras far as you're concerned. (even better than deviceidentifier).

就您而言,它实际上成为唯一的用户标识符。(甚至比设备标识符更好)。

Example:

例子:

I am defining a custom method for creating a UUIDas :

我正在定义用于创建UUIDas的自定义方法:

- (NSString *)createNewUUID 
{
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    CFRelease(theUUID);
    return [(NSString *)string autorelease];
}

You can then store it in KEYCHAINon the very first launch of your app. So that after first launch, we can simply use it from keychain, no need to regenerate it. The main reason for using Keychain to store is: When you set the UUIDto the Keychain, it will persist even if the user completely uninstalls the App and then installs it again. . So, this is the permanent way of storing it, which means the key will be unique all the way.

然后,您可以在KEYCHAIN应用程序第一次启动时将其存储。这样在首次启动后,我们可以简单地从钥匙串中使用它,无需重新生成它。使用Keychain来存储的主要原因是:当您设置UUID为Keychain时,即使用户完全卸载App然后重新安装它也会持续存在。. 因此,这是存储它的永久方式,这意味着密钥将一直是唯一的。

     #import "SSKeychain.h"
     #import <Security/Security.h>

On applictaion launch include the following code :

在应用程序启动时包含以下代码:

 // getting the unique key (if present ) from keychain , assuming "your app identifier" as a key
       NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];
      if (retrieveuuid == nil) { // if this is the first time app lunching , create key for device
        NSString *uuid  = [self createNewUUID];
// save newly created key to Keychain
        [SSKeychain setPassword:uuid forService:@"your app identifier" account:@"user"];
// this is the one time process
}

Download SSKeychain.m and .h file from sskeychainand Drag SSKeychain.m and .h file to your project and add "Security.framework" to your project. To use UUID afterwards simply use :

sskeychain下载 SSKeychain.m 和 .h 文件 并将 SSKeychain.m 和 .h 文件拖到您的项目中,并将“Security.framework”添加到您的项目中。要在之后使用 UUID,只需使用:

NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];

回答by diadyne

Perhaps you can use:

也许你可以使用:

[UIDevice currentDevice].identifierForVendor.UUIDString

Apple's documentation describes identifierForVender as follows:

Apple 的文档对 identifierForVender 的描述如下:

The value of this property is the same for apps that come from the same vendor running on the same device. A different value is returned for apps on the same device that come from different vendors, and for apps on different devices regardless of vendor.

对于来自在同一设备上运行的同一供应商的应用程序,此属性的值是相同的。对于来自不同供应商的同一设备上的应用程序以及不同供应商的不同设备上的应用程序,将返回不同的值。

回答by ylechelle

You may want to consider using OpenUDIDwhich is a drop-in replacement for the deprecated UDID.

您可能需要考虑使用OpenUDIDwhich 是已弃用的UDID.

Basically, to match the UDID, the following features are required:

基本上,要匹配UDID,需要以下功能:

  1. unique or sufficiently unique (a low probability collision is probably very acceptable)
  2. persistence across reboots, restores, uninstalls
  3. available across apps of different vendors (useful to acquire users via CPI networks) -
  1. 独特或足够独特(低概率碰撞可能是非常可接受的)
  2. 重启、恢复、卸载的持久性
  3. 可跨不同供应商的应用程序使用(有助于通过 CPI 网络获取用户)-

OpenUDIDfulfills the above and even has a built-in Opt-Out mechanism for later consideration.

OpenUDID满足上述要求,甚至有一个内置的选择退出机制供以后考虑。

Check http://OpenUDID.orgit points to the corresponding GitHub. Hope this helps!

检查http://OpenUDID.org它指向相应的 GitHub。希望这可以帮助!

As a side note, I would shy away from any MAC address alternative. While the MAC address appears like a tempting and universal solution, be sure that this low hanging fruit is poisoned. The MAC address is very sensitive, and Apple may very well deprecate access to this one before you can even say "SUBMIT THIS APP"... the MAC network address is used to authenticate certain devices on private lans (WLANs) or other virtual private networks (VPNs). .. it's even more sensitive than the former UDID!

作为旁注,我会回避任何 MAC 地址替代方案。虽然 MAC 地址看起来像是一个诱人的通用解决方案,但请确保这个低悬的果实是有毒的。MAC 地址非常敏感,在您甚至可以说“提交此应用程序”之前,Apple 很可能会弃用对这个地址的访问……MAC 网络地址用于验证专用局域网 (WLAN) 或其他虚拟专用设备上的某些设备网络 (VPN)。..比之前的UDID还要敏感!

回答by Mathew Waters

I'm sure Apple have annoyed many people with this change. I develop a bookkeeping appfor iOS and have an online service to sync changes made on different devices. The service maintains a database of all devices and the changes that need to be propagated to them. Therefore it's important to know which devices are which. I'm keeping track of devices using the UIDevice uniqueIdentifier and for what it's worth, here are my thoughts.

我敢肯定,Apple 的这一变化惹恼了很多人。我为 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.

  • 生成 UUID 并存储在用户默认值中?不好,因为当用户删除应用程序时,这不会持续存在。如果他们稍后再次安装,在线服务不应创建新的设备记录,这将浪费服务器上的资源并给出包含相同设备记录两次或多次的设备列表。如果用户重新安装该应用程序,他们将看到不止一个“Bob 的 iPhone”。

  • 生成 UUID 并存储在钥匙串中?这是我的计划,因为即使卸载应用程序它仍然存在。但是当将 iTunes 备份恢复到新的 iOS 设备时,如果备份是加密的,钥匙串就会被传输。如果新旧设备都在使用中,这可能会导致两个设备包含相同的设备 ID。即使设备名称相同,这些也应列为在线服务中的两个设备。

  • 生成哈希 MAC 地址和捆绑 ID?这看起来是我需要的最佳解决方案。通过使用 bundle id 进行散列,生成的设备 id 不会使设备能够跨应用程序跟踪,并且我获得了应用程序+设备组合的唯一 ID。

It's interesting to note that Apple's own documentation refers to validating MacApp Store receipts by computing a hash of the system MAC address plus the bundle id and version. So this seems allowable by policy, whether it passes through app review I don't yet know.

有趣的是,Apple 自己的文档提到通过计算系统 MAC 地址加上包 ID 和版本的哈希来验证MacApp Store 收据。所以这似乎是政策允许的,我还不知道它是否通过了应用程序。

回答by Nate

It looks like for iOS 6, Apple is recommending you use the NSUUID class.

看起来对于 iOS 6,Apple 建议您使用NSUUID 类

From the message now in the UIDevicedocs for uniqueIdentifierproperty:

从现在UIDevice文档中的消息中获取uniqueIdentifier属性:

Deprecated in iOS 5.0. Use the identifierForVendor property of this class or the advertisingIdentifier property of the ASIdentifierManager class instead, as appropriate, or use the UUID method of the NSUUID class to create a UUID and write it to the user defaults database.

在 iOS 5.0 中已弃用。根据需要使用此类的 identifierForVendor 属性或 ASIdentifierManager 类的 AdvertisingIdentifier 属性,或使用 NSUUID 类的 UUID 方法创建 UUID 并将其写入用户默认数据库。

回答by Ashvin Ajadiya

May help: use below code it will always Unique except you erase(Format) your device.

可能会有所帮助:使用下面的代码它将始终是唯一的,除非您擦除(格式化)您的设备。

UIDevice *myDevice=[UIDevice currentDevice];
NSString *UUID = [[myDevice identifierForVendor] UUIDString];