Oli*_*ain 498 deprecated uidevice ios
刚刚看到UIDevice uniqueIdentifier属性在iOS 5中已弃用,在iOS 7及更高版本中不可用.似乎没有替代方法或财产可用或即将出现.
我们的许多现有应用程序都严格依赖此属性来唯一标识特定设备.我们如何处理这个问题呢?
2011 - 2012年文件中的建议是:
特别注意事项
不要使用uniqueIdentifier属性.要创建特定于应用程序的唯一标识符,可以调用该
CFUUIDCreate函数创建一个UUID,并使用NSUserDefaults该类将其写入默认数据库.
但是,如果用户卸载并重新安装应用程序,则此值将不同.
Dar*_*ust 271
如果用户卸载并重新安装应用程序,CFUUIDCreate 则创建的UUID 是唯一的:每次都会获得一个新的UUID .
但是您可能希望它不是唯一的,即当用户卸载并重新安装应用程序时它应该保持不变.这需要一些努力,因为最可靠的每设备标识符似乎是MAC地址.您可以查询MAC并将其用作UUID.
编辑:当然,需要始终查询同一界面的MAC.我想最好的选择是en0.即使接口没有IP /关闭,MAC也始终存在.
编辑2:正如其他人所指出的,iOS 6以来的首选解决方案是- [UIDevice identifierForVendor].在大多数情况下,您应该能够将其用作旧版本的替代品-[UIDevice uniqueIdentifier](但是第一次启动应用时创建的UUID是Apple似乎希望您使用的).
编辑3:所以这个主要观点不会在评论噪声中丢失:不要使用MAC作为UUID,使用MAC创建哈希.每次都会创建相同的结果,即使在重新安装和应用程序中也是如此(如果散列以相同的方式完成).无论如何,现在(2013)除了在iOS <6.0上需要"稳定"的设备标识符之外,这是不再需要的.
编辑4:在iOS 7中,Apple现在总是在查询MAC时返回固定值,以专门阻止MAC作为ID方案的基础.所以你现在真的应该使用- [UIDevice identifierForVendor]或者创建一个每安装的UUID.
Ser*_*tov 91
您UDID已经可以使用Apple的替代品.亲切的家伙gekitz写了类别UIDevice,将UDID根据设备mac-address和bundle标识符生成某种类型.
你可以在github上找到代码
Mat*_*Mat 61
根据@moonlight提出的链接,我做了几次测试,似乎是最好的解决方案.正如@DarkDust所说,该方法将检查en0哪个始终可用.
有两个选项:
uniqueDeviceIdentifier(MAC + CFBundleIdentifier的MD5 )
和uniqueGlobalDeviceIdentifier(MAC的MD5),它们总是返回相同的值.
在我完成的测试之下(使用真实设备):
#import "UIDevice+IdentifierAddition.h"
NSLog(@"%@",[[UIDevice currentDevice] uniqueDeviceIdentifier]);
NSLog(@"%@",[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]);
Run Code Online (Sandbox Code Playgroud)
XXXX21f1f19edff198e2a2356bf4XXXX - (WIFI)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (WIFI)GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX - (3G)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (3G)GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX - (GPRS)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (GPRS)GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX - (AirPlane模式)UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (AirPlane模式)GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX - 删除并安装应用程序后删除并重新安装应用程序XXXX7dc3c577446a2bcbd77935bdXXXX(Wi-Fi)后的(Wi-Fi)
希望它有用.
编辑:
正如其他人所指出的,iOS 7中的这个解决方案不再有用,因为uniqueIdentifier现在不再可用,现在查询MAC地址总是返回02:00:00:00:00:00
小智 56
看一下这个,
我们可以使用Keychain而不是NSUserDefaultsclass来存储UUID创建的CFUUIDCreate.
通过这种方式,我们可以避免UUID重新安装娱乐,并获得UUID相同的应用程序甚至用户卸载并重新安装相同.
UUID 将在用户重置设备时重新创建.
我用SFHFKeychainUtils尝试了这个方法,它就像一个魅力.
Sam*_*han 48
创建自己的UUID,然后将其存储在Keychain中.因此,即使您的应用程序被卸载,它仍然存在.在许多情况下,即使用户在设备之间迁移(例如完全备份和还原到另一个设备),它也会持续存在.
实际上,只要您担心,它就会成为唯一的用户标识符.(甚至比设备标识符更好).
例:
我正在定义一个创建UUIDas 的自定义方法:
- (NSString *)createNewUUID
{
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return [(NSString *)string autorelease];
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以在KEYCHAIN首次启动应用时将其存储.因此,首次启动后,我们可以简单地从钥匙串使用它,无需重新生成它.使用Keychain存储的主要原因是:当您设置UUIDKeychain时,即使用户完全卸载App然后再次安装,它也会持续存在..因此,这是存储它的永久方式,这意味着密钥将一直是唯一的.
#import "SSKeychain.h"
#import <Security/Security.h>
Run Code Online (Sandbox Code Playgroud)
在应用程序启动时包括以下代码:
// 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
}
Run Code Online (Sandbox Code Playgroud)
从sskeychain下载SSKeychain.m和.h文件 并将SSKeychain.m和.h文件拖到项目中,并将"Security.framework"添加到项目中.之后使用UUID只需使用:
NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];
Run Code Online (Sandbox Code Playgroud)
小智 17
也许你可以使用:
[UIDevice currentDevice].identifierForVendor.UUIDString
Run Code Online (Sandbox Code Playgroud)
Apple的文档描述了identifierForVender,如下所示:
对于来自同一设备上运行的同一供应商的应用,此属性的值相同.对于来自不同供应商的同一设备上的应用程序以及不同供应商的不同设备上的应用程序,将返回不同的值.
小智 14
您可能需要考虑使用OpenUDID哪个是已弃用的替代品UDID.
基本上,要匹配UDID,需要以下功能:
OpenUDID 实现上述目标,甚至还有一个内置的Opt-Out机制供以后考虑.
检查http://OpenUDID.org它指向相应的GitHub.希望这可以帮助!
作为旁注,我会回避任何MAC地址替代方案.虽然MAC地址看起来像一个诱人的通用解决方案,但请确保这种低悬的水果中毒.MAC地址非常敏感,Apple甚至可以拒绝访问此地址,甚至可以说"提交此应用程序"...... MAC网络地址用于验证私有设备(WLAN)或其他虚拟专用设备上的某些设备网络(VPN)...它比以前的UDID更敏感!
Mat*_*ers 11
我相信苹果公司已经让很多人对这种变化感到恼火.我为iOS 开发了一个簿记应用程序,并提供在线服务来同步在不同设备上进行的更改.该服务维护所有设备的数据库以及需要传播给它们的更改.因此,了解哪些设备是哪些设备非常重要.我正在使用UIDevice uniqueIdentifier跟踪设备以及它的价值,这是我的想法.
生成UUID并存储在用户默认值中?不好,因为当用户删除应用程序时,这不会持续存在.如果稍后再次安装,则在线服务不应创建新设备记录,这会浪费服务器上的资源并提供包含相同设备的设备列表两次或更多次.如果他们重新安装应用程序,用户会看到列出多个"Bob的iPhone".
生成UUID并存储在钥匙串中?这是我的计划,因为它甚至在卸载应用程序时仍然存在.但是,当将iTunes备份恢复到新的iOS设备时,如果备份已加密,则会传输钥匙串.如果旧设备和新设备都在使用中,这可能导致两个设备包含相同的设备ID.这些应该在在线服务中列为两个设备,即使设备名称相同.
生成MAC地址和包ID的哈希值?这看起来是我需要的最佳解决方案.通过使用包ID进行散列,生成的设备ID不会启用跨应用程序跟踪设备,我会获得应用程序+设备组合的唯一ID.
有趣的是,Apple自己的文档是指通过计算系统MAC地址的散列加上捆绑包ID和版本来验证Mac App Store收据.所以这似乎是政策所允许的,无论是通过我还不知道的应用评论.
Ash*_*iya 11
可以提供帮助:使用以下代码,除了擦除(格式化)您的设备外,它始终是唯一的.
UIDevice *myDevice=[UIDevice currentDevice];
NSString *UUID = [[myDevice identifierForVendor] UUIDString];
Run Code Online (Sandbox Code Playgroud)
我还建议转换uniqueIdentifier到这个开源库(真正的2个简单类别),利用设备的MAC地址和应用程序包标识符在您的应用程序中生成可用作UDID替换的唯一ID.
请记住,与UDID不同,这个数字对于每个应用都会有所不同.
您只需要导入包含NSString和UIDevice类别并调用[[UIDevice currentDevice] uniqueDeviceIdentifier]如下:
#import "UIDevice+IdentifierAddition.h"
#import "NSString+MD5Addition.h"
NSString *iosFiveUDID = [[UIDevice currentDevice] uniqueDeviceIdentifier]
Run Code Online (Sandbox Code Playgroud)
你可以在Github上找到它:
适用于iOS 5的UIDevice和UniqueIdentifier
以下是类别(只是.m文件 - 检查标头的github项目):
的UIDevice + IdentifierAddition.m
#import "UIDevice+IdentifierAddition.h"
#import "NSString+MD5Addition.h"
#include <sys/socket.h> // Per msqr
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
@interface UIDevice(Private)
- (NSString *) macaddress;
@end
@implementation UIDevice (IdentifierAddition)
////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Private Methods
// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Accidentally munged during previous update. Fixed thanks to erica sadun & mlamb.
- (NSString *) macaddress{
int mib[6];
size_t len;
char *buf;
unsigned char *ptr;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
if ((mib[5] = if_nametoindex("en0")) == 0) {
printf("Error: if_nametoindex error\n");
return NULL;
}
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 1\n");
return NULL;
}
if ((buf = malloc(len)) == NULL) {
printf("Could not allocate memory. error!\n");
return NULL;
}
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 2");
return NULL;
}
ifm = (struct if_msghdr *)buf;
sdl = (struct sockaddr_dl *)(ifm + 1);
ptr = (unsigned char *)LLADDR(sdl);
NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
*ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
free(buf);
return outstring;
}
////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Public Methods
- (NSString *) uniqueDeviceIdentifier{
NSString *macaddress = [[UIDevice currentDevice] macaddress];
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
NSString *stringToHash = [NSString stringWithFormat:@"%@%@",macaddress,bundleIdentifier];
NSString *uniqueIdentifier = [stringToHash stringFromMD5];
return uniqueIdentifier;
}
- (NSString *) uniqueGlobalDeviceIdentifier{
NSString *macaddress = [[UIDevice currentDevice] macaddress];
NSString *uniqueIdentifier = [macaddress stringFromMD5];
return uniqueIdentifier;
}
@end
Run Code Online (Sandbox Code Playgroud)
的NSString + MD5Addition.m:
#import "NSString+MD5Addition.h"
#import <CommonCrypto/CommonDigest.h>
@implementation NSString(MD5Addition)
- (NSString *) stringFromMD5{
if(self == nil || [self length] == 0)
return nil;
const char *value = [self UTF8String];
unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(value, strlen(value), outputBuffer);
NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
[outputString appendFormat:@"%02x",outputBuffer[count]];
}
return [outputString autorelease];
}
@end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
158634 次 |
| 最近记录: |