[[[关于keychain这个东西的概念可以到这里学习:
https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/index.html, 简言之就是每个应用程序都有一个可以用于安全保存一些如密码、认证等信息的keychain,通过对应用签名时的一些设置,还可以利用keychain的方式实现同一开发者签证(就是相同bundle seed)下的不同应用之间共享信息的操作。比如你有一个开发者帐户,并开发了两个不同的应用A和B,然后通过对A和B的keychain access group这个东西指定共用的访问分组,就可以实现共享此keychain中的内容。而且,对比NSUserDefaults的一点不同之处就是此信息不会随应用的删除而消失!
关于Keychain的应用,Apple提供了一个叫GenericKeychain的例子程序,在这里:http://developer.apple.com/library/ios/#samplecode/GenericKeychain/Listings/Classes_KeychainItemWrapper_h.html#//apple_ref/doc/uid/DTS40007797-Classes_KeychainItemWrapper_h-DontLinkElementID_9,其中封装了一个简化Keychain操作的类:KeychainItemWrapper,可以拿来直接使用,记得加入Security.framework!
]]]
参考代码如下:
KeychainItemWrapper *wrapper = [[KeychainItemWrapperalloc]initWithIdentifier:@"password"accessGroup:nil];
// 设置数据
NSString *uuid = [[NSUUID UUID] UUIDString];
[wrapper setObject:uuid forKey:kSecAttrAccount];
// 读取数据
NSString *uuid2 = [wrapperobjectForKey:kSecAttrAccount];
[wrapper release];
关于keychain access groups的设置,传统方法是在Xcode项目target的Build Settings的Code Signing段中加入Code Signing Entitlements的配置文件,加入group信息,详细操作如下。
1)首先,打开keychain sharing配置。
2)在build setting里可以看到,配置文件的索引。
3)这是配置文件:
Keychain Access Groups是一个在不同应用见公用钥匙串的标志。
$(AppIdentifierPrefix)是每个开发账号的id,在member center里可以看到。
com.icomwell:这个icomwell一般是公司名称。
.icomwell:第二个icomwell一般是参数名称。
不同的应用,配置相同的Groups后,就可以公用保存的数据。
现在再看下这个示例代码:
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"password" accessGroup:nil];
password是这个groups下的一个标识符。一个标识符下可以有多个参数。以字典形式保存。
比如
// 设置数据
NSString *uuid = [[NSUUID UUID] UUIDString];
[wrapper setObject:uuid forKey:kSecAttrAccount];
[wrapper setObject:@"test" forKey:kSecAttrLabel];
这就设置了两个key的value。每个key根据根据配置的class来,比如这个kSecClassGenericPassword包括这么多key
/*
These are the default constants and their respective types,
available for the kSecClassGenericPassword Keychain Item class:
kSecAttrAccessGroup -CFStringRef
kSecAttrCreationDate -CFDateRef
kSecAttrModificationDate - CFDateRef
kSecAttrDescription -CFStringRef
kSecAttrComment -CFStringRef
kSecAttrCreator -CFNumberRef
kSecAttrType - CFNumberRef
kSecAttrLabel -CFStringRef
kSecAttrIsInvisible -CFBooleanRef
kSecAttrIsNegative -CFBooleanRef
kSecAttrAccount -CFStringRef
kSecAttrService -CFStringRef
kSecAttrGeneric -CFDataRef
See the header file Security/SecItem.h for more details.
*/
// 读取数据
NSString *uuid2 = [wrapper objectForKey:kSecAttrAccount];
[wrapper release];
当遇到奔溃时,可以查到错误码:比如add时遇到–25299,这个一般是key和对应的class不匹配造成的,其他的可以查看文档。
matching时遇到–25300,这个是查询不到参数。
[[[经过测试有以下经验同大家分享:
1.相同bundle下生成的程序都可以共享相同group的keyChain.
相同bundle解释下就是:比如:2个程序分别使用的provision对应bundle是com.jv.key1和com.jv.key2,那你配置文件肯定是{Identifer}.com.jv.{name},其中identifer是苹果生成的随机串号,可以在申请证书时看到,复制过来即可,name可以自己取,程序中指定属于哪个Group即可。
2.如果你在 addkey时,没有指定group,则会默认添加你keychain-access-groups里第一个group,如果你没有设置Entitlements,则默认使用对应的程序的bundle name,比如com.jv.key1,表示只能给自己程序使用。
3.如果你程序添加的group并不存在你的配置文件中,程序会奔溃,表示无法添加。因此你只能添加你配置文件中支持的keychain。]]]