Once you enable your app to run into the background you have to start caring about data protection, and specifically the keychain access attribute. Consider a scenario like this:
Your app is run by the user and everything is good.
The user presses the Home button and your app moves to the background.
Shortly thereafter the system suspends your app.
At some point in the future, the system needs memory and thus removes your suspended app from memory.
The user locks their device.
At some point in the future a location event causes the system to launch your app in the background.
Your ‘willFinishLaunchingWithOptions’ app delegate method runs. If it attempts to access a keychain item with
kSecAttrAccessible
set to kSecAttrAccessibleWhenUnlocked
, that access will fail because the device is locked.
How you resolve this depends on the nature of your app:
If you only need your database when the app is showing UI, you can defer this access until the app is on screen. The app can only come on screen if the device is unlocked.
If you need your database while in the background, you can set
kSecAttrAccessible
to something less secure. The exact value depends on how your app gets run in the background. Most background execution is deferred until first unlock, and thus you can use kSecAttrAccessibleAfterFirstUnlock
. However, some background execution can happen before first unlock, in which case you’ll need kSecAttrAccessibleAlways
. This is measurably less secure.
Obviously it’s best to keep your data as secure as possible, so you should only use the second approach if your database is absolutely critical to the background operation of your app. You may be able to come up with a hybrid approach, where you split your database in two, using better protection in general but less protection for the critical-to-background-execution stuff. Or if you only need to write to your database, you could temporarily write new data to a less secure database and then consolidate things when the device is unlocked.
Keep in mind that the keychain is not the only place where data protection applies. Ideally you should protect your files on disk as well, using the various file protection modes. The preferred API for this is
NSURLFileProtectionKey
in
NSURL
, but most of the documentation you’ll find for the older
NSFileProtectionKey
in in
NSFileManager
.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"