使用iphone sdk保存在钥匙串中时出错

mam*_*mcx 28 iphone keychain ios4

我使用Apple包装器作为钥匙串,并尝试在其上保存一个项目(在模拟器中运行,ios 4.1).

我之前没有使用过钥匙扣.

我收到此错误:

无法添加钥匙串项目.错误 - 25299

在KeychainItemWrapper.m第304行:

// No previous item found; add the new one.
result = SecItemAdd((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL);
NSAssert( result == noErr, @"Couldn't add the Keychain Item." );
Run Code Online (Sandbox Code Playgroud)

这是我保存的方式:

- (void) saveKey:(NSString *)key value:(NSString *)value {
    KeychainItemWrapper *keyItem = [[KeychainItemWrapper alloc] initWithIdentifier:key accessGroup:nil];
    [keyItem setObject:value forKey:(id)kSecValueData];
    [keyItem release];
}
Run Code Online (Sandbox Code Playgroud)

这是api试图保存的值:

<CFBasicHash 0x7231f60 [0x320d380]>{type = mutable dict, count = 5,
entries =>
2 : <CFString 0x2e6eb98 [0x320d380]>{contents = "labl"} = <CFString 0x2fb018 [0x320d380]>{contents = ""}
3 : <CFString 0x2e6efb8 [0x320d380]>{contents = "v_Data"} = <CFString 0x727de60 [0x320d380]>{contents = "dit8"}
4 : <CFString 0x2e6ebc8 [0x320d380]>{contents = "acct"} = <CFString 0x2fb018 [0x320d380]>{contents = ""}
5 : <CFString 0x2e6eb58 [0x320d380]>{contents = "desc"} = <CFString 0x2fb018 [0x320d380]>{contents = ""}
6 : <CFString 0x2e6ebe8 [0x320d380]>{contents = "gena"} = <CFString 0x2ffd08 [0x320d380]>{contents = "userCode"}
}
Run Code Online (Sandbox Code Playgroud)

Dwa*_*ill 61

我知道这是几个月前发生的,但我遇到了同样的问题而且很痛苦,所以我想我会分享.我通过添加这一行来解决它:

[self.keychainItemWrapper setObject:@"MY_APP_CREDENTIALS" forKey:(id)kSecAttrService];
//@"MY_APP_CREDENTIALS" can be any string.
Run Code Online (Sandbox Code Playgroud)

我发现这个博客条目非常有用:"在数据库术语中,您可以认为它们是两个属性kSecAttrAccount的唯一索引,kSecAttrService要求这两个属性的组合对于钥匙串中的每个条目都是唯一的." (来自http://useyourloaf.com/blog/2010/4/28/keychain-duplicate-item-when-adding-password.html).

此外,在使用此代码的Apple示例项目中,他们在app delegate中实例化KeychainItemWrapper.我不知道是否有必要,但我希望尽可能密切关注他们的例子:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//there will be some standard code here.
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MY_APP_CREDENTIALS" accessGroup:nil];
self.keychainWrapper = wrapper;
[self.keychainWrapper setObject:@"MYOBJECT" forKey:(id)kSecAttrService];
[wrapper release];
}
Run Code Online (Sandbox Code Playgroud)

我认为这是包装器代码中的一个错误.逻辑基本上说"这个条目是否已经存在?不,它没有.好的,我会添加它.哎呀,你不能添加它,因为它已经存在了."

您可能还需要设置kSecAttrAccount; 我没有尝试过它而没有设置这个值,因为它打算保存密码配置的用户名:

[self.wrapper setObject:txtUserName.text forKey:(id)kSecAttrAccount];   
Run Code Online (Sandbox Code Playgroud)


Ano*_*mie 9

根据文档,您获得的错误-25299是"errSecDuplicateItem",这意味着您尝试添加的项目已存在.查看KeychainItemWrapper的链接代码,我猜这个SecItemCopyMatching调用失败了,错误除了errSecItemNotFound(-25300)之外.


mat*_*odv 6

您可以使用Buzz Andersen的SFHFKeychainUtils轻松地使用钥匙串存储和获取值.

  1. 下载并复制您的项目SFHFKeychainUtils.h和.m
  2. 将Security.framework添加到Framework文件夹
  3. 确保将这些文件添加到目标中
  4. 导入SFHFKeychainUtils.h您要使用它的位置

这是关于如何使用此库的一个小例子.

// To store data
NSError *error = nil;
[SFHFKeychainUtils storeUsername:username andPassword:password forServiceName:kStoredData updateExisting:YES error:&error];

// To retrieve data
NSString *password = [SFHFKeychainUtils getPasswordForUsername:username andServiceName:kStoredData error:&error];

// To delete data from keychain
[SFHFKeychainUtils deleteItemForUsername:username andServiceName:kStoredData error:&error];
Run Code Online (Sandbox Code Playgroud)