美文网首页iOS
获取设备UUID,并使用keychain存储

获取设备UUID,并使用keychain存储

作者: jaychowbin | 来源:发表于2016-04-12 09:40 被阅读388次

          获取到UUID后,如果用NSUserDefaults存储,当程序被卸载后重装时,再获得的UUID和之前就不同了。使用keychain存储可以保证程序卸载重装时,UUID不变。但当刷机后,UUID还是会改变的。但这仍是目前为止最佳的解决办法了,如果有更好的解决办法,欢迎留言。

    1.新建一个工程,看一下自己的Bundle Id.这个Bundle Id 要和你用真机测试时的证书上面的Bundle Id相匹配。

    2.Target - Capabilities - Keychain Sharing  改为ON

    然后,在左侧的目录会自动生成Entitlements文件,不用自己创建了。

    注意:Bundle Identifier、Keychain Sharing的Keychain Groups、Entitlements文件的Keychain Access Groups的第一个元素,它们要保持上图所示的一致性。

    设置好了以后可以运行下程序,没问题可以进行下一步。

    3.接下来,就是UUID类和keychain类了(我也是从网上搬运来的,作者看到勿喷。。。)

    UUID.h

    #import  <Foundation/Foundation.h>

    @interface UUID : NSObject

    +(NSString *)getUUID;

    @end

    UUID.m

    #import "UUID.h"

    #import "KeyChainStore.h"

    @implementation UUID

    +(NSString *)getUUID

    {

    NSString * strUUID = (NSString *)[KeyChainStore load:@"com.company.app.usernamepassword"];

    //首次执行该方法时,uuid为空

    if ([strUUID isEqualToString:@""] || !strUUID)

    {

    //生成一个uuid的方法

    CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);

    strUUID = (NSString *)CFBridgingRelease(CFUUIDCreateString (kCFAllocatorDefault,uuidRef));

    //将该uuid保存到keychain

    [KeyChainStore save:KEY_USERNAME_PASSWORD data:strUUID];

    }

    return strUUID;

    }

    @end

    KeyChainStore.h

    #import <Foundation/Foundation.h>

    @interface KeyChainStore : NSObject

    + (void)save:(NSString *)service data:(id)data;

    + (id)load:(NSString *)service;

    + (void)deleteKeyData:(NSString *)service;

    @end

    KeyChainStore.m

    #import "KeyChainStore.h"

    @implementation KeyChainStore

    + (NSMutableDictionary *)getKeychainQuery:(NSString *)service {

    return [NSMutableDictionary dictionaryWithObjectsAndKeys:

    (id)kSecClassGenericPassword,(id)kSecClass,

    service, (id)kSecAttrService,

    service, (id)kSecAttrAccount,

    (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,

    nil];

    }

    + (void)save:(NSString *)service data:(id)data {

    //Get search dictionary

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    //Delete old item before add new item

    SecItemDelete((CFDictionaryRef)keychainQuery);

    //Add new object to search dictionary(Attention:the data format)

    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];

    //Add item to keychain with the search dictionary

    SecItemAdd((CFDictionaryRef)keychainQuery, NULL);

    }

    + (id)load:(NSString *)service {

    id ret = nil;

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    //Configure the search setting

    //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue

    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];

    [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];

    CFDataRef keyData = NULL;

    if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {

    @try {

    ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];

    } @catch (NSException *e) {

    NSLog(@"Unarchive of %@ failed: %@", service, e);

    } @finally {

    }

    }

    if (keyData)

    CFRelease(keyData);

    return ret;

    }

    + (void)deleteKeyData:(NSString *)service {

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    SecItemDelete((CFDictionaryRef)keychainQuery);

    }

    @end

    将这两个类添加到工程中

    4.新建一个pch文件,给pch文件添加的内容如下:

    #define  KEY_USERNAME_PASSWORD @"com.company.app.usernamepassword"

    #define  KEY_USERNAME @"com.company.app.username"

    #define  KEY_PASSWORD @"com.company.app.password"

    添加pch文件方法可参照:创建.pch文件 - 简书

    5.最后,在viewController里面添加头文件,调用

    NSString * uuid= [UUID getUUID];

    NSLog(@"UUID = %@",uuid);

    打印出来的是这个样子:UUID = F6574AFA-6B6E-4699-A889-799944AA3861

    然后呢就可以多试几次,看看各种情况下,会不会改变

    PS:重装系统没有试过,但是卸载APP重装后,UUID不会变,要是有人测试过重装系统后,一定将结果告诉我喔!

    相关文章

      网友评论

      • 蛐蛐_:重装系统会变,楼主怎么解决的
      • WhatHurtsMore:我想删除UUID怎么做
      • 陈饥饿:看不懂#define KEY_USERNAME @"com.company.app.username"这个是用来做什么的,如果自己的项目里面要用到service应该传什么?
      • writeSpace:不管用

      本文标题:获取设备UUID,并使用keychain存储

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