美文网首页
iOS获取手机唯一标示

iOS获取手机唯一标示

作者: 木子雨廷t | 来源:发表于2019-12-27 11:57 被阅读0次
    随着苹果爸爸的不断改革,现在想获取一台手机的唯一标示是难上加难,但是办法还是有的,下面就来介绍一下最简单安全的办法,获取手机唯一标示。(首先说明这种方法的弊端,手机系统升级后这个唯一的ID也会变化)

    以前废弃的方法就不一一细说了,直接说笔者是怎么做的吧

    • 采用Keychain+[[NSUUID UUID] UUIDString] 的方法

    开发者可以在应用第一次启动时仅仅调用一次,然后利用Keychain将该串存储起来,如果Keychain存储了UUID就不需要再存储了。如果用户删除该应用再次安装时,Keychain存储的UUID也不会消失,所以能保证唯一识别该设备。

    • keychain介绍
      iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储。相对于NSUserDefaults、文件保存等一般方式,keychain保存更为安全,而且keychain里保存的信息不会因App被删除而丢失,所以在重装App后,keychain里的数据还能使用。

    • keychain代码

    #import <Foundation/Foundation.h>
    #import <Security/Security.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface ZXXKeyChain : NSObject
    
    
    /**
     添加keyChain数据
    
     @param data s数据
     @param key key值
     */
    + (void)addKeychainData:(id)data forKey:(NSString *)key;
    
    /**
     根据key值获取数据
    
     @param key key值
     @return 返回数据
     */
    + (id)getKeychainDataForKey:(NSString *)key;
    
    /**
     根据key值删除数据
    
     @param key key值
     */
    + (void)deleteKeychainDataForKey:(NSString *)key;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "ZXXKeyChain.h"
    
    
    @implementation ZXXKeyChain
    
    
    + (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
        return [NSMutableDictionary dictionaryWithObjectsAndKeys:
                (__bridge id)kSecClassGenericPassword,(id)kSecClass,// 标识符(kSecAttrGeneric通常值位密码)
                service, (__bridge id)kSecAttrService,// 服务(kSecAttrService)
                service, (__bridge id)kSecAttrAccount,// 账户(kSecAttrAccount)
                (__bridge id)kSecAttrAccessibleAfterFirstUnlock,(__bridge id)kSecAttrAccessible,// kSecAttrAccessiblein变量用来指定这个应用何时需要访问这个数据
                nil];
    }
    
    + (void)addKeychainData:(id)data forKey:(NSString *)key {
        // 获取查询字典
        NSMutableDictionary *keychainQuery = [self getKeychainQuery:key];
        // 在添加之前先删除旧数据
        SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
        // 添加新的数据到字典
        [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData];
        // 将数据字典添加到钥匙串
        SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL);
    }
    
    + (id)getKeychainDataForKey:(NSString *)key {
        id ret = nil;
        NSMutableDictionary *keychainQuery = [self getKeychainQuery: key];
        
        [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: %@", key, e);
            } @finally {
                
            }
        }
        
        return ret;
    }
    
    + (void)deleteKeychainDataForKey:(NSString *)key {
        NSMutableDictionary *keychainQuery = [self getKeychainQuery: key];
        SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
    }
    
    • 具体实现在AppDelegate实现以下代码
    - (void)creatOnlyID{
        NSString *uuidStr = [[NSUUID UUID] UUIDString];
        NSString *getStr = [ZXXKeyChain getKeychainDataForKey:@"UUID"];
        if (getStr.length == 0) {
            [ZXXKeyChain addKeychainData:uuidStr forKey:@"UUID"];
        }
    }
    

    这种方法还是存在问题,当手机系统升级后,KeyChain中存储的值会变化,现在还没有好的对策,欢迎大神@指正

    相关文章

      网友评论

          本文标题:iOS获取手机唯一标示

          本文链接:https://www.haomeiwen.com/subject/qdeloctx.html