http://www.cnblogs.com/samniu/p/3673781.html?utm_source=tuicool&utm_medium=referral
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.youkuaiyun.com/u011439689/article/details/18707387