iOS UUID配合keychain的替换方案实现
iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个iOS程序都有一个独立的keychain存储。相对于NSUserDefaults、文件保存等一般方式,keychain保存更为安全,而且keychain里保存的信息不会因App被删除而丢失,所以在重装App后,keychain里的数据还能使用。
在应用里使用使用keyChain,我们需要导入Security.framework
要先声明公共区的名称,官方文档管这个名称叫“keychain access group”,声明的方法是新建一个plist文件,名字随便起,内容如下:
“yourAppID.com.yourCompany.whatever”就是你要起的公共区名称
获取UUID 并保存到keychain中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #pragma mark--获取设备UUID -( NSString *) uuid { if ([CHKeychain load:UUIDKEY]) { NSString *result = [CHKeychain load:UUIDKEY]; return result; } else { CFUUIDRef puuid = CFUUIDCreate( nil ); CFStringRef uuidString = CFUUIDCreateString( nil , puuid ); NSString * result = ( NSString *)CFStringCreateCopy( NULL , uuidString); CFRelease(puuid); CFRelease(uuidString); [CHKeychain save:UUIDKEY data:result]; return [result autorelease]; } return nil ; } |
CHKeychain 的实现代码(需要导入Security.framework):
CHKeychain.h
1 2 3 4 5 6 7 8 9 10 | #import <Foundation/Foundation.h> @interface CHKeychain : NSObject + ( void )save:( NSString *)service data:( id )data; + ( id )load:( NSString *)service; + ( void )deleteData:( NSString *)service; @end |
CHKeychain.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #import "CHKeychain.h" @implementation CHKeychain + ( 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:( NSData *)keyData]; } @catch ( NSException *e) { NSLog (@ "Unarchive of %@ failed: %@" , service, e); } @finally { } } if (keyData) CFRelease(keyData); return ret; } + ( void ) delete :( NSString *)service { NSMutableDictionary *keychainQuery = [ self getKeychainQuery:service]; SecItemDelete((CFDictionaryRef)keychainQuery); } @end |
参考:http://blog.csdn.net/u011439689/article/details/18707387
分类:
技术笔记
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!