我使用以下代码从iPhone密钥链中检索登录凭据:
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Test" accessGroup:nil];
NSString *username = [wrapper objectForKey:(id)kSecAttrAccount];
NSString *password = [wrapper objectForKey:(id)kSecValueData];
[wrapper release];
我的印象是,当用户第一次启动应用程序时,用户名和密码都无法从密钥链中检索到,所以username
和password
应该等于nil
。但是,我无法使用NSLog
输出这些变量中的任何一个。
有什么建议吗?
发布于 2012-02-22 01:28:17
您的假设是错误的-在创建时,"kSecAttrAccount“和"kSecValueData”没有设置为nil。它们被设置为空字符串(即"")。因此,此代码将返回true:
[username isEqualToString:@""] // returns true on creation
发布于 2010-08-31 12:59:01
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Test" accessGroup:nil];
NSString *username = [wrapper objectForKey:(id)kSecAttrAccount];
NSString *password = [wrapper objectForKey:(id)kSecValueData];
// initially all these are empty
NSLog(@"username - %@", username); // username -
NSLog(@"password - %@", password); // password -
//if empty set your credentials
if ( [username isEqualToString:@""] ) {
[wrapper setObject:@"your username here" forKey:(id)kSecAttrAccount];
}
if ( [password isEqualToString:@""] ) {
[wrapper setObject:@"your password here" forKey:(id)kSecValueData];
}
//get the latest credentials - now you have the set values
username = [wrapper objectForKey:(id)kSecAttrAccount];
password = [wrapper objectForKey:(id)kSecValueData];
NSLog(@"username - %@", username); // username - your username here
NSLog(@"password - %@", password); // password - your password here
// reset your keychain items - if needed
[wrapper resetKeychainItem];
[wrapper release];
发布于 2012-08-26 22:40:57
我也犯了同样的错误,我检查了KeychainItemWrapper.m
文件中writeToKeychain
函数的返回值。返回值等于errSecDuplicateItem
。我不知道为什么,但似乎SecItemCopyMatching
函数不能正常工作。(对于我的其他工作正常的项目)。
我现在更改了代码,并为自己工作:在KeychainItemWrapper.m
文件中更新了writeToKeychain
的代码:
- (void)writeToKeychain
{
NSDictionary *attributes = NULL;
NSMutableDictionary *updateItem = NULL;
OSStatus result;
if (SecItemCopyMatching((CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes) == noErr)
{
// First we need the attributes from the Keychain.
updateItem = [NSMutableDictionary dictionaryWithDictionary:attributes];
// Second we need to add the appropriate search key/values.
[updateItem setObject:[genericPasswordQuery objectForKey:(id)kSecClass] forKey:(id)kSecClass];
// Lastly, we need to set up the updated attribute list being careful to remove the class.
NSMutableDictionary *tempCheck = [self dictionaryToSecItemFormat:keychainItemData];
[tempCheck removeObjectForKey:(id)kSecClass];
#if TARGET_IPHONE_SIMULATOR
// Remove the access group if running on the iPhone simulator.
//
// Apps that are built for the simulator aren't signed, so there's no keychain access group
// for the simulator to check. This means that all apps can see all keychain items when run
// on the simulator.
//
// If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
// simulator will return -25243 (errSecNoAccessForItem).
//
// The access group attribute will be included in items returned by SecItemCopyMatching,
// which is why we need to remove it before updating the item.
[tempCheck removeObjectForKey:(id)kSecAttrAccessGroup];
#endif
// An implicit assumption is that you can only update a single item at a time.
result = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)tempCheck);
NSAssert( result == noErr, @"Couldn't update the Keychain Item." );
}
else
{
// No previous item found; add the new one.
result = SecItemAdd((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL);
NSLog(@"%@",keychainItemData);
NSLog(@"res : %ld",result);
if(result == (OSStatus)errSecDuplicateItem)
{
NSLog(@"updttttt");
// First we need the attributes from the Keychain.
updateItem = [NSMutableDictionary dictionaryWithDictionary:attributes];
// Second we need to add the appropriate search key/values.
[updateItem setObject:[genericPasswordQuery objectForKey:(id)kSecClass] forKey:(id)kSecClass];
// Lastly, we need to set up the updated attribute list being careful to remove the class.
NSMutableDictionary *tempCheck = [self dictionaryToSecItemFormat:keychainItemData];
[tempCheck removeObjectForKey:(id)kSecClass];
#if TARGET_IPHONE_SIMULATOR
// Remove the access group if running on the iPhone simulator.
//
// Apps that are built for the simulator aren't signed, so there's no keychain access group
// for the simulator to check. This means that all apps can see all keychain items when run
// on the simulator.
//
// If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
// simulator will return -25243 (errSecNoAccessForItem).
//
// The access group attribute will be included in items returned by SecItemCopyMatching,
// which is why we need to remove it before updating the item.
[tempCheck removeObjectForKey:(id)kSecAttrAccessGroup];
#endif
// An implicit assumption is that you can only update a single item at a time.
result = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)tempCheck);
NSAssert( result == noErr, @"Couldn't update the Keychain Item." );
return;
}//if(result == errSecDuplicateItem)*
NSAssert( result == noErr, @"Couldn't add the Keychain Item." );
}
}
https://stackoverflow.com/questions/3595650
复制相似问题