我有以下代码在钥匙串中创建钥匙串项目:
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
[dict setObject: (__bridge id) kSecClassGenericPassword forKey: (__bridge id) kSecClass];
[dict setObject: MYKEY forKey: (__bridge id) kSecAttrService];
[dict setObject: @"0" forKey: (__bridge id) kSecValueData];
SecItemAdd ((__bridge CFDictionaryRef) dict, NULL);
哪个工作正常。如果我想更改此项,是否有人可以为SecItemUpdate提供准确的语法?
更新:使用以下内容:
NSMutableDictionary *query = [NSMutableDictionary dictionary];
NSMutableDictionary *attributesToUpdate = [NSMutableDictionary dictionary];
[query setObject: (__bridge id) kSecClassGenericPassword forKey: (__bridge id) kSecClass];
[query setObject: MYKEY forKey: (__bridge id) kSecAttrService];
[query setObject: (id) kCFBooleanTrue forKey: (__bridge id) kSecReturnData];
NSString *numberOfBalloonsString = [NSString stringWithFormat:@"%d", numberOfBalloonsUsed];
NSData *numberOfBalloonsData = [numberOfBalloonsString dataUsingEncoding:NSUTF8StringEncoding];
[attributesToUpdate setObject: numberOfBalloonsData forKey:(__bridge id)kSecValueData];
OSStatus error = SecItemUpdate ((__bridge CFDictionaryRef) query, (__bridge CFDictionaryRef) attributesToUpdate);
NSLog(@"Error #: %ld", error);
我收到错误代码-50 =
传递给函数的一个或多个参数无效。
答案 0 :(得分:6)
SecItemUpdate
非常有记录。
query
SecItemUpdate
参数记录为查询(在其他函数中使用)以及模糊语句:“指定要更改其值的项目”。这似乎意味着您必须在此字典中包含您想要更改的现有属性值,但我认为您不会这样做。我发现您可以使用相同的query
来获取要更新的项目的属性。
attributes
参数应该是SecItemCopyMatching
的结果,其中kSecValueData
键和值已添加且任何属性都已更改。
答案 1 :(得分:4)
一个迟到的答案,但仍然是一个答案:
我一直在努力更新钥匙串中的物品,但我的情境有点不同。
我可以成功添加一个钥匙串项目(使用SecItemAdd
),但在同一个项目上调用SecItemUpdate
失败了,而臭名昭着的errSecParam -50
。
更糟糕的是;如果钥匙串项已经存在(因此我立即调用SecItemUpdate
),更新完全没有问题。
我完全不知道为什么会发生这种情况......
实际上非常简单,我只是删除了“params”,直到大坏-50
满意为止。当我从kSecClass
检索到的词典中删除kSecItemCopyMatching
时发生了这种情况
这是我的代码:
// If the item already exists, we update it instead
if (SecItemCopyMatching((__bridge CFDictionaryRef)self.searchQueryDict, (CFTypeRef *)&foundItem) == errSecSuccess) {
NSMutableDictionary *updateDict = (__bridge NSMutableDictionary *)foundItem;
[updateDict addEntriesFromDictionary:dictToSave];
[updateDict removeObjectForKey:(__bridge id)kSecClass];
OSStatus updateSuccess = SecItemUpdate((__bridge CFDictionaryRef)self.updateQueryDict,
(__bridge CFDictionaryRef)updateDict);
NSAssert(updateSuccess == errSecSuccess, @"Couldn't save the dirty info to the keychain, might want to log the updateSuccess (%d)", updateSuccess);
}
作为参考,我使用了以下词典
self.searchQueryDict
包含:
(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword
(__bridge id)kSecAttrService : service
(__bridge id)kSecAttrGeneric : [identifier dataUsingEncoding:NSUTF8StringEncoding]
(__bridge id)kSecMatchLimit : (__bridge id)kSecMatchLimitOne
(__bridge id)kSecReturnAttributes : (__bridge id)kCFBooleanTrue
(__bridge id)kSecReturnData : (__bridge id)kCFBooleanTrue
self.updateQueryDict
包含:
(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService : service,
(__bridge id)kSecAttrGeneric : [identifier dataUsingEncoding:NSUTF8StringEncoding]
dictToSave
应包含需要更改的值(格式正确)
删除kSecClass
为我解决了问题。