在Apple提供的KeychainItemWrapper类问题上遇到很多问题后,我可以让它工作,但后来我在代码上做了一些事情,看起来现在处于不稳定的状态。 实际上我有原始的KeychainItemWrapper类,我只是更改了以下行来检查结果:
OSStatus cpy = SecItemCopyMatching((CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes);
NSLog(@"cpy result=%d", cpy);
if (cpy == noErr)
{
....
}
else
{
// No previous item found; add the new one.
result = SecItemAdd((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL);
if(result == errSecDuplicateItem) {
result = SecItemDelete((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData]);
NSLog(@"result=%d", result);
}
NSAssert( result == noErr, @"Couldn't add the Keychain Item." );
}
第一个cpy变量返回-25300(无法找到该项)
SecItemAdd返回errSecDuplicateItem(-25299该项已存在)
然后我试图删除项目,如果函数说项目存在,SecItemDelete再次返回-25300,那么......现在我无法理解发生了什么。
我使用带有iOS 6.1.3的iPad运行此测试,不管怎样?有没有办法完全重置钥匙串并从头开始?
感谢您的帮助
答案 0 :(得分:3)
我在此链接中提供的信息后发现了问题: What makes a keychain item unique (in iOS)?
"对于类kSecClassGenericPassword的keychain项,主键是kSecAttrAccount和kSecAttrService的组合。"
看起来Apple提供的KeychainItemWrapper示例类使用了错误的组合键,或者对我试图做的事情没有用。
无论如何我删除了那个类,现在我使用了一些简化的方法,我把代码放在这里,可能对其他人有帮助:
- (NSString*) getKeyChainItem:(NSString*)key {
NSString* keyChainValue = NULL;
NSData *attributes = NULL;
NSMutableDictionary* keyChainParams = [self createKeyChainDict:key];
[keyChainParams setObject:key forKey:(id)kSecAttrService];
[keyChainParams setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
if (SecItemCopyMatching((CFDictionaryRef)keyChainParams, (CFTypeRef *)&attributes) == noErr)
{
keyChainValue = [[[NSString alloc] initWithBytes:[attributes bytes] length:[attributes length]
encoding:NSUTF8StringEncoding] autorelease];
}
return keyChainValue;
}
- (BOOL) setKeyChainItem:(NSString*)key withValue:(NSString*)value {
NSMutableDictionary* keyChainParams = [self createKeyChainDict:key];
[keyChainParams setObject:[value dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData];
return SecItemAdd((CFDictionaryRef)keyChainParams, NULL) == noErr;
}
- (NSMutableDictionary*)createKeyChainDict:(NSString*)key {
NSMutableDictionary* keyChainParams = [[NSMutableDictionary alloc] init];
[keyChainParams setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
[keyChainParams setObject:@"" forKey:(id)kSecAttrLabel];
[keyChainParams setObject:@"" forKey:(id)kSecAttrDescription];
[keyChainParams setObject:key forKey:(id)kSecAttrService];
[keyChainParams setObject:key forKey:(id)kSecAttrAccount];
return keyChainParams;
}
如何使用它:
NSString* myValue = [self getKeyChainItem:@"myStoredVvalue"];
[self setKeyChainItem:@"myStoredVvalue" withValue:@"12345"];