I had a major case of “struggleface” when trying to work with the KeychainItemWrapper for iOS. I wanted it to be simple – just take a username and password and put it in the iOS Keychain for secure retrieval later. Turns out that I had to spend an entire work day and do a lot of Googling to get it working so I’m posting this to try and bring all the pieces together.
Obstacle #1: Automatic Reference Counting (ARC)
My project uses ARC for its memory management. As it turns out, the KeychainItemWrapper class from Apple does not support ARC out of the box. Step one for me should have been to find an ARC-friendly version of the class, but I had no idea until I got in there. I attempted to retrofit the one provided by Apple, but there are a few nuances with toll-free bridging that I don’t fully understand, so I went in search of someone who’s already invented the wheel. There’s a GitHub Gist repository that provided exactly what I needed: KeychainItemWrapper ARCified
Obstacle #2: Error Message Obscurity
Somehow in my novice experimentation with storing credentials in the keychain I ended up getting a keychainItem on the keychain for a particular test user that couldn’t be updated or removed. I kept getting a cryptic error code (–25299) as I debugged the app when attempting to sign in with that user’s credentials. I spent…well…too long trying to find what the keychain error codes meant.
While I started off reviewing the Keychain Services developer documentation page, I didn’t see the section describing the result codes. This is the section that was most helpful in determining what “-25299” meant: errSecDuplicateItem – The item already exists. In my case, the item was in there but the keychain search method didn’t find it, so it tried to add it again, causing a “duplicate keychain item” error message.
Eventually I got things to store to the keychain fine for some test user accounts but my primary test account (the one I started with at the beginning of the day) still ran into the “duplicate keychain item” error no matter what I tried. Signing out of my app didn’t work. Sending a resetKeychainItem message to my KeychainItemWrapper instance didn’t work. Even deleting the app from the simulator didn’t work. I ended up just needing to reset my simulator completely. This was simple to do:
iOS Simulator -> Reset Content and Settings…
Things began to work perfectly after the reset. Unfortunately, I spent the majority of the day spinning over the error message trying to find ways to programmatically either remove the keychainItem or reset it so that it would no longer be a duplicate. I’d have been finished hours earlier if I would have just reset the simulator. In fact, since I reset the simulator, I’ve been unable to reproduce the scenario I’d gotten myself into. Otherwise I would list the obstacles I was trying to work through for the rest of the day as well.
As far as I can tell, it was all stemming from whatever I did at the beginning of the day to get the malformed keychainItem in the keychain. The simulator reset did the trick.
Go home happy.