2015-01-04 64 views
1

有人可以告訴我miastake在哪裏?我現在不知道。在模擬器中使用SecItemUpdate並出現錯誤-50

//獲取查詢迪科

+ (NSMutableDictionary *)keychainQueryDictionary:(NSString *)service 
{ 
    return [NSMutableDictionary dictionaryWithObjectsAndKeys: 
      (__bridge id)kSecClassGenericPassword,(__bridge id)kSecClass, 
      service, (__bridge id)kSecAttrService, 
      service, (__bridge id)kSecAttrAccount, 
      (__bridge id)kSecAttrAccessibleAfterFirstUnlock,(__bridge id)kSecAttrAccessible, 
      nil]; 
} 

//這裏我保存一些數據到鑰匙串

+ (OSStatus)saveData:(id)data service:(NSString *)serviceIdentify 
{ 
    NSMutableDictionary *keychainQuery = [self keychainQueryDictionary:serviceIdentify]; 

    SecItemDelete((__bridge CFDictionaryRef)keychainQuery); 

    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData]; 

    return SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL); 
} 

//刪除調度研究

+ (OSStatus)deleteData:(NSString *)serviceIdentify 
{ 
    NSMutableDictionary *keychainQuery = [self keychainQueryDictionary:serviceIdentify]; 
    return SecItemDelete((__bridge CFDictionaryRef)keychainQuery); 
} 

//這裏我嘗試更新keychian中的一個項目,但我得到一個錯誤-50,但我不知道哪裏是錯誤的參數

+ (OSStatus)updataData:(id)data service:(NSString *)serviceIdentify 
{ 
    NSMutableDictionary *keychainQuery = [self keychainQueryDictionary:serviceIdentify]; 
    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; 
    [keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; 

    CFDataRef keyData = NULL; 
    OSStatus status = errSecNotAvailable; 
    if (SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) { 
     NSMutableDictionary *queryDict = nil; 
     NSDictionary *ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData]; 
     queryDict = [NSMutableDictionary dictionaryWithDictionary:ret]; 
     [queryDict setObject:[keychainQuery objectForKey:(__bridge id)kSecClass] forKey:(__bridge id)kSecClass]; 

     NSMutableDictionary *attributesToUpdate = [self keychainQueryDictionary:serviceIdentify]; 
     [attributesToUpdate setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData]; 

     status = SecItemUpdate((__bridge CFDictionaryRef)queryDict,(__bridge CFDictionaryRef)attributesToUpdate); 
    } 

    return status; 
} 

//讀取調度研究

+ (id)loadData:(NSString *)serviceIdentify 
{ 
    id ret = nil; 
    NSMutableDictionary *keychainQuery = [self keychainQueryDictionary:serviceIdentify]; 
    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; 
    [keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; 
    CFDataRef keyData = NULL; 
    if (SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) { 
     ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData]; 
    } 
    return ret; 
} 

回答

0

-50是errSecParam。我認爲你有參數翻轉SecItemUpdate。第一個參數是用於查找需要更新的匹配項目的搜索查詢。這可能應該通過調用keychainQueryDictionary方法來創建。第二個參數應該包含更改 - 在您的示例中,這是您正在處理的kSecValueData的新數據,但字典通常不包含任何搜索屬性。在你的例子中,它看起來像它也包含了所有的搜索屬性,這將導致一個errSecParam。

作爲單獨的一點,還要注意keychainQuery字典中不適用於更新的任何值也會導致errSecParam。如果這些值存在,則可以簡單地將其刪除,例如:

CFDictionaryRemoveValue(keychainQuery, kSecReturnData); 
CFDictionaryRemoveValue(keychainQuery, kSecMatchLimit); 
相關問題