0

I am trying to save NSMutableDictionary in iOS keychain using KeychainItemWrapper classes. But I am not able to save it. I am getting error

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't add the Keychain Item.'

Here is my data to be saved

    {
    country = USA;
    id = 3;
    name = "Test User";
    photo = "http://www.mydomain.com/images/user1.jpg";
    result = true;
    "country" = 1;
}

Here is my code

// Call to save 
[self storeLoggedInUserInfoInKeychainWithDictionary:dict];


        -(void)storeLoggedInUserInfoInKeychainWithDictionary:(NSMutableDictionary*)dict
    {
        // Save Login Credentials
        KeychainItemWrapper* loginUserkeychain = [[KeychainItemWrapper alloc] initWithIdentifier:LOGIN_USER_SERVICE accessGroup:nil];
        NSString *error;
        [loginUserkeychain setObject:(__bridge id)(kSecAttrAccessibleWhenUnlocked) forKey:(__bridge id)(kSecAttrAccessible)];
        NSData *dictionaryRep = [NSPropertyListSerialization dataFromPropertyList:dict format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
        [loginUserkeychain setObject:dictionaryRep forKey:(__bridge id)(kSecValueData)];
    }

    -(NSMutableDictionary*)fetchLoggedInUserInfoFromKeychain
    {
        KeychainItemWrapper* loginUserkeychain = [[KeychainItemWrapper alloc] initWithIdentifier:LOGIN_USER_SERVICE accessGroup:nil];
        NSString *error;
        //When the NSData object object is retrieved from the Keychain, you convert it back to NSDictionary type
        NSData *dictionaryRep = [loginUserkeychain objectForKey:(__bridge id)(kSecValueData)];
        NSDictionary *dictionary = [NSPropertyListSerialization propertyListFromData:dictionaryRep mutabilityOption:NSPropertyListImmutable format:nil errorDescription:&error];
        if (error) {
            NSLog(@"%@", error);
        }
        return [NSMutableDictionary dictionaryWithDictionary:dictionary];
    }

    -(void)resetLoggedInUserInfoFromKeychain
    {
        KeychainItemWrapper* loginUserkeychain = [[KeychainItemWrapper alloc] initWithIdentifier:LOGIN_USER_SERVICE accessGroup:nil];
        [loginUserkeychain resetKeychainItem];
    }

Can anybody tell me whats wrong in above code ? Thanks in advance.

iOSAppDev
  • 2,755
  • 4
  • 39
  • 77

1 Answers1

1

After few attempts & research using below code I am able to save the data in keychain. If any one is interested can have a look at below code

    -(void)storeLoggedInUserInfoInKeychainWithDictionary:(NSMutableDictionary*)dict
{
    // Create encoded data
    NSData *encodedData= [NSKeyedArchiver archivedDataWithRootObject:dict];

    // Create encoded string from data
    NSString *encodedString= [encodedData base64EncodedString];

    // Save Login Credentials
    KeychainItemWrapper* tranxkeychain = [[KeychainItemWrapper alloc] initWithIdentifier:LOGIN_USER_KEYCHAIN accessGroup:nil];
    [tranxkeychain setObject:(__bridge id)(kSecAttrAccessibleWhenUnlocked) forKey:(__bridge id)(kSecAttrAccessible)];
    [tranxkeychain setObject:LOGIN_USER_SERVICE forKey: (__bridge id)kSecAttrService];
    [tranxkeychain setObject:LOGIN_USER_INFO forKey:(__bridge id)(kSecAttrAccount)];
    [tranxkeychain setObject:encodedString forKey:(__bridge id)(kSecValueData)];
}

-(NSDictionary*)fetchLoggedInUserInfoFromKeychain
{
    KeychainItemWrapper* tranxkeychain = [[KeychainItemWrapper alloc] initWithIdentifier:LOGIN_USER_KEYCHAIN accessGroup:nil];
    [tranxkeychain setObject:(__bridge id)(kSecAttrAccessibleWhenUnlocked) forKey:(__bridge id)(kSecAttrAccessible)];
    [tranxkeychain setObject:LOGIN_USER_SERVICE forKey: (__bridge id)kSecAttrService];

    // Get decoded string
    NSString *decodedString=[tranxkeychain objectForKey:(__bridge id)(kSecValueData)];

    // Get decoded data
    NSData *decodedData= [NSData dataFromBase64String:decodedString];
    NSDictionary *dict =[NSKeyedUnarchiver unarchiveObjectWithData:decodedData];
    return dict;
}

-(void)resetLoggedInUserInfoFromKeychain
{
    KeychainItemWrapper* tranxkeychain = [[KeychainItemWrapper alloc] initWithIdentifier:LOGIN_USER_KEYCHAIN accessGroup:nil];
    [tranxkeychain resetKeychainItem];
}
iOSAppDev
  • 2,755
  • 4
  • 39
  • 77