首页 文章

应用程序在保存钥匙串数据时崩溃

提问于
浏览
2

我正在使用 KeychainItemWrapper 类来保存钥匙串中的数据,但我的应用程序崩溃了崩溃日志 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't add the Keychain Item.'

这是一种在钥匙串中写入数据的方法

- (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." );
     }
}

My app is crashing at

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

带有断言错误消息 Assertion failure in -[KeychainItemWrapper writeToKeychain]

以下是keychainItemData中指定的值

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

我知道这里曾经问过很多类似的问题,但没有任何帮助 .

谁能帮我吗 ?是否还有其他方法可以在钥匙串中保存数据 .

提前致谢 .

1 回答

  • -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." );
         }
    }
    

相关问题