Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing arbitrary keys/values in iOS

Is there a way to store arbitrary keys/values in iOS, I know I could create column that store JSON key-value in SQLite but I want something more efficient so I could be able to get only the values that I need from a queried record.

Preferably If I could do this without having external database (like LevelDB) but if you think this might be the only way, let me know which one you prefer.

Update:

The data will hold articles (long html articles, title and date, and other undefined data) retrieved from the server and other meta data, it will be retrieved and displayed every time the user opens the app. (thats why NSUserDefaults will not work for this use case)

like image 519
Jimmy Avatar asked Dec 05 '13 17:12

Jimmy


1 Answers

I've written an App that deals with 50MB texts(about 10,000 articles in HTML). They're indexed by an articleID. I've used LevelDB, raw Sqlite, Sqlite with FMDB, CoreData and NSUserDefaults in this App.

Here's what I've learned:

LevelDB gives you the arbitrary key/value access pattern and the reading speed is extremely fast if you're reading them sequentially. But if you need to read a key randomly (by not using it's iterator), it is much slower than Sqlite.

Raw Sqlite is fast for random reading if you use it correctly. (Use indexes, cover indexes, etc.) But you will lose the ability to read and write arbitrary key/value.

FMDB gives you a nice Objective-C API but 50% CPU time is wasted when converting data between Objective C and C (NSString <-> char*) (It's still a lot faster than Core Data, 4X+)

Personally I think Core Data sucks. So I won't recommend it to anyone for any usage. Sorry I don't want to recall those pain when using CoreData.

NSUserDefaults is best for user setting and only for user setting, definitely not a solution for long articles.

I use raw Sqlite and Google Protocol Buffer.

Protocol Buffer is extremely fast for encoding and decoding. It also gives you the ability to add new fields by modifying it's .proto file, no DB scheme change is required. You can store several related keys in a single proto, let's say articleMetaData.proto contains the title, author and publishDate, if some time later you need to add modifyDate you just add it to the proto file and store the binary in Sqlite in the same column.

like image 84
Jay Zhao Avatar answered Sep 18 '22 11:09

Jay Zhao