Better way to save serialize NSDictionary, NSArray to the Keychain, and also support NSData
rivera-ernesto opened this issue · 8 comments
Instead of using the fixed kDelimeter property list serialization could be used which would be more robust and also provide more complex object trees.
http://stackoverflow.com/questions/9948698/store-nsdictionary-in-keychain
That's a nice idea. Taking it a step farther, the API could then be simplified to save & retrieve a single object (presumably but not necessarily a dictionary), without an explicit key (or perhaps with an optional key). Automatic (and extensible) support for NSData, NSString, NSArray, NSDictionary, NSDate, and NSNumber.
The idea isn't bad, but I think one wants to be careful with just how much data you store in the keychain. The keychain should not be used as a total NSUserDefaults replacement. So, generalizing Lockbox simply to store and retrieve plists is a clever improvement. But I am not sure it's the right thing to do. My intent was to be able to store things in the keychain easily, but to overload it (or make it TOO easy to do so.) Let me think about it. Of course, someone can fork the repo and do it themselves too. :-)
It's a legitimate concern, but caveat developer. I'll look at migrating my fork. There are obvious advantages: not having to adapt new objects (like my NSDate patch), and as r-e points out, no worrying about delimiter conflicts.
My thinking: expose the object methods, and convert them to encode/decode with NSPropertyListSerialization, and then (I think) remove the class-specific API. NSPropertyListSerialization produces NSData, so the NSUTF8StringEncoding step disappears.
The existing Lockbox API could be preserved by simply NSPropertyListSerialization internally, but I lean toward a leaner API...
I've just published jklundell/KCMutableDictionary as a morning project. It's basically an NSMutableDictionary (with minor limitations) that persists itself transparently in the keychain. It handles all the NSPropertyListSerialization-supported classes: NSData, NSString, NSArray, NSDictionary, NSDate, and NSNumber.
Have a look. Feedback welcome.
Nicely done, Jonathan.
For what it's worth, I've tested storing a megabyte of data into the keychain before. It seemed to work fine, but I didn't do any stress-testing: I was just looking for a limit. Note that I am not recommending such use of the keychain!
JSON format would be even lighter (and more readable) than a Plist string.
Edit:
Also adopting JSON will allow to store complete trees of objects whereas now arrays, sets and dictionaries' contents are limited to strings.
I have just pushed an update to Lockbox that deprecates all the setXxx and related getters, and added methods for archiving and unarchiving objects of any kind that conform to NSSecureCoding.