2016-04-06 2 views
2

Я использую KeychainItemWrapper класс для сохранения данных в связке ключей, но мое приложение врезаться с журналом аварии Нагрузочный приложение из-за неперехваченного исключением «NSInternalInconsistencyException», причина: «Не удалось добавить Брелок для ключей.App падает на сохранение данных в связке ключей

Вот метод, чтобы записать данные в брелке

- (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); 

     NSAssert(result == noErr, @"Couldn't add the Keychain Item."); 
    } 
} 

Моего приложение разваливается на

result = SecItemAdd((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL); 

с сообщением об ошибке утверждения отказа утверждения - [KeychainItemWrapper writeToKeychain]

Вот значения, присвоенные i п keychainItemData

Printing description of self->keychainItemData: 
{ 
    acct = ""; 
    desc = ""; 
    gena = "com.xyz.abc"; 
    labl = ""; 
    "v_Data" = "ABCDSS-ABCDSS-ABCDSS-TEST-DATA"; 
} 

Я знаю, что подобные вопросы были предложены здесь много раз, но ничего не помощи для меня.

Может ли кто-нибудь помочь мне? Есть ли другой подход к сохранению данных в цепочке ключей.

Заранее спасибо.

+0

У меня такая же проблема, как и вы, но это произошло только в симуляторе. Если вы используете реальное устройство, возможно, не произойдет никакого сбоя. Но почему это происходит на симуляторе? –

ответ

-1

Использование self.keychainItemData вместо keychainItemData в вашем методе?

- (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:self.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:self.keychainItemData], NULL); 

     NSAssert(result == noErr, @"Couldn't add the Keychain Item."); 
    } 
} 
+0

Почему downvoting? Глядя на этот код, keychainItemData - всего лишь нуль. – Elendir