Search code examples
iosobjective-ckeychain

Unable to retrieve data from SecItemCopyMatching


I am adding an item to the Keychain, then later I want to get that item's value. The problem is, it turns out to be an empty string. What am I doing wrong? Thanks!

//add item to keychain
NSDictionary *secItem = @{ (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
                           (__bridge id)kSecAttrService : [[NSBundle mainBundle] bundleIdentifier],
                           (__bridge id)kSecAttrAccount : myKeyVar,
                           (__bridge id)kSecValueData : [myValue dataUsingEncoding:NSUTF8StringEncoding],
                           (__bridge id)kSecAttrSynchronizable : @YES };

OSStatus status = SecItemAdd((__bridge CFDictionaryRef)secItem, NULL);
//successfully adds it

//query for existing item
NSDictionary *query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
                        (__bridge id)kSecAttrService : [[NSBundle mainBundle] bundleIdentifier],
                        (__bridge id)kSecAttrAccount : keyToSearchForVar,
                        (__bridge id)kSecAttrSynchronizable : @YES,
                        (__bridge id)kSecReturnAttributes : (__bridge id)kCFBooleanTrue};

CFDictionaryRef valueAttributes = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query,
                                      (CFTypeRef *)&valueAttributes);
NSDictionary *attributes = (__bridge_transfer NSDictionary *)valueAttributes;
//attributes has 8 key/value pairs but I don't see the stored encoded value as one of them

if (status == errSecSuccess) {
    NSString* myString = [[NSString alloc] initWithData:[attributes objectForKey:(__bridge id)kSecValueData] encoding:NSUTF8StringEncoding];
    //myString is @""
}

Solution

  • The problem was that I defined kSecReturnAttributes to ask it to return the attributes, but did not define kSecReturnData in order to return the actual data, which is kind of important. Adding this line in the query solved the problem:

    (__bridge id)kSecReturnData : (__bridge id)kCFBooleanTrue}