Keychain Query Always Returns errSecItemNotFound After Upgrading to iOS 13
I've had a similar issue where I was getting errSecItemNotFound
with any Keychain-related action but only on a simulator. On real device it was perfect, I've tested with latest Xcodes (beta, GM, stable) on different simulators and the ones that were giving me a hard time were iOS 13 ones.
The problem was that I was using kSecClassKey
in query attribute kSecClass
, but without the 'required' values (see what classes go with which values here) for generating a primary key:
kSecAttrApplicationLabel
kSecAttrApplicationTag
kSecAttrKeyType
kSecAttrKeySizeInBits
kSecAttrEffectiveKeySize
And what helped was to pick kSecClassGenericPassword
for kSecClass
and provide the 'required' values for generating a primary key:
kSecAttrAccount
kSecAttrService
See here on more about kSecClass types and what other attributes should go with them.
I came to this conclusion by starting a new iOS 13 project and copying over the Keychain wrapper that was used in our app, as expected that did not work so I've found this lovely guide on using keychain here and tried out their wrapper which no surprise worked, and then went line by line comparing my implementation with theirs.
This issue already reported in radar: http://openradar.appspot.com/7251207
Hope this helps.
After half a day of experimentation I discovered that using a pretty basic instance of kSecClassGenericPassword I had the problem on both the simulator and real hardware. After having a read over of the docs I noticed that kSecAttrSynchronizable has a kSecAttrSynchronizableAny. To accept any value for any other attribute, you simply don't include it in the query. That's a clue.
I found that when I included kSecAttrSynchronizable set to kSecAttrSynchronizableAny the queries all worked. Of course I could also set it to either kCFBooleanTrue (or *False) if I actually do want to filter on that value.
Given that attribute everything seems to work as expected for me. Hopefully this will save some other people a half day of mucking around with test code.