ios设备的唯一标示符

1.已禁用-[UIDevice uniqueIdentifier]
  苹果总是把用户的隐私看的很重要。-[UIDevice uniqueIdentifier]在iOS5实际在iOS5的时候已经被遗弃了,但是iOS7中已经完全的禁用了它。Xcode5甚至不会允许你编译包含了指引到-[UIDevice uniqueIdentifier]的app。此外,iOS7之前的使用了-[UIDevice uniqueIdentifier] 的app如果在iOS7上运行,它不会返回设备的UUID,而是会返回一串字符串,以FFFFFFFF开头,跟着-[UIDevice identifierForVendor]的十六进制值。

2.MAC地址不能再用来设别设备
  还有一个生成iOS设备唯一标示符的方法是使用iOS设备的Media Access Control(MAC)地址。一个MAC地址是一个唯一的号码,它是物理网络层级方面分配给网络适配器的。这个地址苹果还有其他的名字,比如说是硬件地址(Hardware Address)或是Wifi地址,都是指同样的东西。
  有很多工程和框架都使用这个方法来生成唯一的设备ID。比如说ODIN。然而,苹果并不希望有人通过MAC地址来分辨用户,所以如果你在iOS7系统上查询MAC地址,它现在只会返回02:00:00:00:00:00。
3.现在苹果明确的表明你应该使用-[UIDevice identifierForVendor]或是-[ASIdentifierManager advertisingIdentifier]来作为你框架和应用的唯一标示符。坦白的来说,应对这些变化也不是那么的难,见以下代码片段:
NSString *identifierForVendor = [[UIDevice currentDevice].identifierForVendor UUIDString];
NSString *identifierForAdvertising = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
每种方法都适配一种特别的用法:
  identifierForVendor对供应商来说是唯一的一个值,也就是说,由同一个公司发行的的app在相同的设备上运行的时候都会有这个相同的标识符。然而,如果用户删除了这个供应商的app然后再重新安装的话,这个标识符就会不一致。
  advertisingIdentifier会返回给在这个设备上所有软件供应商相同的 一个值,所以只能在广告的时候使用。这个值会因为很多情况而有所变化,比如说用户初始化设备的时候便会改变。
4.由于identifierForVendor删除了这个供应商的app然后再重新安装的话,这个标识符就会不一致,所以要解决这个问题可以把第一次生成的唯一标示符,保存到keyChain中,当应用被删除后keyChain中的数据还在,下次在从keyChain中取就OK了
废话就讲到这了,下面是代码:
可以把下面代码直接拷贝去用,改下你的类名就ok了
#define KEY_UDID            @"KEY_UDID"
#define KEY_IN_KEYCHAIN     @"KEY_IN_KEYCHAIN"

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

@implementation APPIdentificationManage
singleton_implementation(APPIdentificationManage)

#pragma mark 获取UUID
/**
 *此uuid在相同的一个程序里面-相同的vindor-相同的设备下是不会改变的
 *此uuid是唯一的,但应用删除再重新安装后会变化,采取的措施是:只获取一次保存在钥匙串中,之后就从钥匙串中获取
 **/
- (NSString *)openUDID
{
    NSString *identifierForVendor = [[UIDevice currentDevice].identifierForVendor UUIDString];
    return identifierForVendor;
}

#pragma mark 保存UUID到钥匙串
- (void)saveUDID:(NSString *)udid
{
    NSMutableDictionary *udidKVPairs = [NSMutableDictionary dictionary];
    [udidKVPairs setObject:udid forKey:KEY_UDID];
    [[APPIdentificationManage sharedAPPIdentificationManage] save:KEY_IN_KEYCHAIN data:udidKVPairs];
}

#pragma mark 读取UUID
/**
 *先从内存中获取uuid,如果没有再从钥匙串中获取,如果还没有就生成一个新的uuid,并保存到钥匙串中供以后使用
 **/
- (id)readUDID
{
    if (_uuid == nil || _uuid.length == 0) {
        NSMutableDictionary *udidKVPairs = (NSMutableDictionary *)[[APPIdentificationManage sharedAPPIdentificationManage] load:KEY_IN_KEYCHAIN];
        NSString *uuid = [udidKVPairs objectForKey:KEY_UDID];
        if (uuid == nil || uuid.length == 0) {
            uuid = [self openUDID];
            [self saveUDID:uuid];
        }
        _uuid = uuid;
    }
    return _uuid;
}

#pragma mark 删除UUID
- (void)deleteUUID
{
    [APPIdentificationManage delete:KEY_IN_KEYCHAIN];
}

#pragma mark 查询钥匙串
- (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
    return [NSMutableDictionary dictionaryWithObjectsAndKeys:
            (__bridge_transfer id)kSecClassGenericPassword,(__bridge_transfer id)kSecClass,
            service, (__bridge_transfer id)kSecAttrService,
            service, (__bridge_transfer id)kSecAttrAccount,
            (__bridge_transfer id)kSecAttrAccessibleAfterFirstUnlock,(__bridge_transfer id)kSecAttrAccessible,
            nil];
}

#pragma mark 将数据保存到钥匙串
- (void)save:(NSString *)service data:(id)data {
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge_transfer id)kSecValueData];
    SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL);
}

#pragma mark 加载钥匙串中数据
- (id)load:(NSString *)service {
    id ret = nil;
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];
    [keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];
    CFDataRef keyData = NULL;
    if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
        @try {
            ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];
        } @catch (NSException *e) {
            NSLog(@"Unarchive of %@ failed: %@", service, e);
        } @finally {
        }
    }
    return ret;
}

#pragma mark 删除钥匙串中数据
- (void)delete:(NSString *)service {
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
}
@end


时间: 2024-10-14 19:08:08

ios设备的唯一标示符的相关文章

iOS编程——经过UUID和KeyChain来代替Mac地址实现iOS设备的唯一标示(OC版)

iOS编程——通过UUID和KeyChain来代替Mac地址实现iOS设备的唯一标示(OC版) 很多的应用都需要用到手机的唯一标示,而且要求这个唯一标示不能因为应用app的卸载或者改变而变化. 在iOS7以前是可以通过Mac地址来实现这个功能的,但是iOS7(包含)以后是无法获得Mac地址的:苹果官方推荐使用UUID,但是每次随着APP的卸载重装,UUID会随之发生变化,那该如何处理呢? 我们需要一个能在app卸载重装后不会改变的值,而keyChain恰巧就可以做到.配合UUID就可以实现了!让

(转)iOS中的唯一标示符

在2013年3月21日苹果已经通知开发者,从2013年5月1日起,访问UIDIDs的程序将不再被审核通过,替代的方案是开发者应该使用“在iOS 6中介绍的Vendor或Advertising标示符”. 苹果已经警告过我们uniqueIdentifier将不能再使用了,并且提供了另外两个可选的.但是在程序中该选择使用哪个呢?本文不会回答这个问题,具体用哪个是由你来根据程序的目的来做决定的. 下面我将列出iOS中目前支持的,以及被废弃的唯一标示符方法,并对其做出相应的解释,希望你看了以后针对唯一标示

现有IOS设备唯一标示符的方案比较

现有IOS设备唯一标示符的方案比较 UDID [[UIDevice currentDevice] uniqueIdentfier] iOS官方最早提供的UDID方案,根据某一公式,使用设备序列号.网卡地址等信息作为参数计算而来,iOS6之后该计算公式发生了改变. 该方法返回的结果在所有应用中都相同,并且卸载应用.刷机.还原设备均不会发生改变,是最为准确的设备唯一标示符. iOS5之后,该方法被标记为废弃!最终,在2013年5月1号之后,AppStore禁止任何使用该方法的应用上架. iOS7中对

iOS 获取设备唯一标示符的方法

在开发中会遇到应用需要记录设备标示,即使应用卸载后再安装也可重新识别的情况,在这写一种实现方式--读取设备的UUID(Universally Unique Identifier)并通过KeyChain记录. 首先iOS中获取设备唯一标示符的方法一直随版本的更新而变化.iOS 2.0版本以后UIDevice提供一个获取设备唯一标识符的方法uniqueIdentifier,通过该方法我们可以获取设备的序列号,这个也是目前为止唯一可以确认唯一的标示符.好景不长,因为该唯一标识符与手机一一对应,苹果觉得

iOS唯一标示符引导

在2013年3月21日苹果已经通知开发者,从2013年5月1日起,访问UIDID的应用将不再能通过审核,替代的方案是开发者应该使用"在iOS 6中介绍的Vendor或Advertising标示符". unique Identifier即将退出,苹果给了我们Vendor和Advertising identifier两个选择,但应该用哪一个?文档并没有给出确切答案,具体使用哪个完全由你根据自己app的目的来决定.下面我将列出iOS中目前支持的,以及被废弃的唯一标示符方法,并对其做出相应的解

iOS唯一标示符

unique Identifier即将退出,苹果给了我们Vendor和Advertising identifier两个选择,但应该用哪一个?文档并没有给出确切答案,具体使用哪个完全由你根据自己app的目的来决定. 在2013年3月21日苹果已经通知开发者,从2013年5月1日起,访问UIDID的应用将不再能通过审核,替代的方案是开发者应该使用"在iOS 6中介绍的Vendor或Advertising标示符". unique Identifier即将退出,苹果给了我们Vendor和Adv

iOS 设备获取唯一标识符汇总

在2013年3月21日苹果已经通知开发者,从2013年5月1日起,访问UIDID的应用将不再能通过审核,替代的方案是开发者应该使用“在iOS 6中介绍的Vendor或Advertising标示符”. unique Identifier即将退出,苹果给了我们Vendor和Advertising identifier两个选择,但应该用哪一个?文档并没有给出确切答案,具体使用哪个完全由你根据自己app的目的来决定.下面我将列出iOS中目前支持的,以及被废弃的唯一标示符方法,并对其做出相应的解释,希望可

iOS6.0以上版本中的唯一标示符的一些总结

在2013年3月21日苹果已经通知开发者,从2013年5月1日起,访问UIDIDs的程序将不再被审核通过,替代的方案是开发者应该使用“在iOS 6中介绍的Vendor或Advertising标示符. 苹果已经警告过我们uniqueIdentifier将不能再使用了,并且提供了另外两个可选的.但是在程序中该选择使用哪个呢? 本文不会回答这个问题,具体用哪个是由你来根据程序的目的来做决定的. 下面我将列出iOS中目前支持的,以及被废弃的唯一标示符方法,并对其做出相应的解释,希望你看了以后针对唯一标示

iOS 唯一标示符 卸载后安装值不变

Vindor标示符 (IDFV-identifierForVendor) 这种叫法也是在iOS 6中新增的,不过获取这个IDFV的新方法被添加在已有的UIDevice类中.跟advertisingIdentifier一样,该方法返回的是一个NSUUID对象. NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; 苹果官方的文档中对identifierForVendor有如下这样的一段描述 : T