Archive for the ‘Objective C’ Category

I have updated my app to support Share Extension and it requires share keychain between containing App and extension, so that I need create a keychain access group. The app was working fine in simulator, but it will crash with the above exception in a real device. When debugging, I found the reason code is -25243.

The keychain wrapper i was using is from this link. https://gist.github.com/dhoerl/1170641

After troubleshooting for a few days, i found that the reason is that I was accessing using the wrong keychain access group.

-25243 is related to keychain permission and I didn’t see this error in simulator because simulator app wasn’t signed

For the sake of context, i set the keychain access group in Target->Keychain sharing, then directly accessed the keychain with the group name.  This is wrong because the actual keychain access group should be $(AppIdentifierPrefix)whatever.you.set. You can find it from entitlements.plist.

I was writing a Share Extension which allows users to share a file to others. The extension will use loadItemForTypeIdentifier to fetch the file’s name and display it to the user. But users must always wait for a while before the UI is updated.

Thanks to this post, I found that it is because that UI wasn’t updated in the main queue. To fix it is very simple, just dispatch the ui updating to the main queue.

dispatch_async(dispatch_get_main_queue(), ^{
//Your UI updating logic
});

My new project requires to share Keychain among containing app and share extension. This requires the support of the keychain access group, which my current wrapper doesn’t support.

The iOS KeychainItemWrapper provided by Apple supports access group, but it doesn’t work in ARC. I found this from github which claims ARCified. https://gist.github.com/dhoerl/1170641

The library is very easy to use, but when i tried to retrieve the stored password, it always gave me NSZeroData. After some research, i found that I need convert NSString to NSData before storing my string data as KSecValueData.

//store value
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:KEYCHAIN_NAME accessGroup:KEYCHAIN_GROUP];
[keychain setObject:[password dataUsingEncoding:NSUTF8StringEncoding] forKey:(__bridge id)kSecValueData];

//retrieve stored value
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:KEYCHAIN_NAME accessGroup:KEYCHAIN_GROUP];
NSData *mySecureData = [keychain objectForKey:(__bridge id)kSecValueData];
NSString *password = [[NSString alloc] initWithData:mySecureData encoding:NSUTF8StringEncoding];

To keep it simple, one reason could be that you detached the view controller inviewDidLoad, instead ofviewDidAppear.