views:

135

answers:

2

Hi all,

I am working on i-Phone app targeting 3.1.3 and later SDK. I want to know the best way to store user's long term data on i-phone without losing performance, consistency and security.

I know, that i can use Core Data, PList and SQL-Lite for storing user specific data in custom formats.But, want to know which one is good to use without compromising app performance and scalability in near future.

Thanks

+3  A: 

It depends. The term "user data" covers a wide scale in size, complexity and usage each of which have different optimal storage strategies.

(1) If size and complexity are low and the usage is primarily controlling the app itself, store the data in the user defaults using NSUserDefaults.

(2) If the size is small and the complexity can be managed by arrays, dictionaries etc then store in a plist. Size counts because all the data stored in a plist is loaded into memory in one chunk.

(3) If the size is very large but the complexity is low e.g. a large number of template records such as an index card system, then use direct SQL. SQL is faster for finding and saving simple and repetitive information in a very large DB.

(4) If the complexity is very high, use Core Data regardless of size. Core Data is specifically designed to manage complex information. If the size is small, use an xml store. If it is large, use a SQL store.

As I gained familiarity with Core Data, I find myself using it for almost everything except user defaults. It has a steep learning curve but once you master it, you have a powerful and easy to use tool for managing application data. I probably use it in situations where it is not optimal just because it speeds development time.

TechZen
Thanks, for your valuable explanation. As per your details, it seems that i can either use SQL DB directly as well as Core Data. Though, the data which i need to store is a small structure with very few attributes and i don't need to take any extra care while storing. So, i am only concern with the performance and the future version of SDK compatibility for my app. Also what if i need to secure or encrypt the data? Is Sqlite providing a way to encrypt the database or secure it using password or i need to go with Core data if i need to secure the data.
AmitSri
It sounds like at present you can just use a plist file. If you implement your data structure with NSArray or similar classes you can just write the top most collection object to disk with the `writeToFile:`method. Once loaded the data remains in memory so performance is very high. This relies on the foundation methods so compatibility is guaranteed going forward. This methods have not changed in nearly 20 years.
TechZen
For security, use the Keychain services. Encrypting the entire database imposes a huge processor load and is usually not necessary. On iOS simply putting the DB anywhere but the documents folder blocks all external software access to the DB. However, it is possible. I have seen custom NSManagedObject subclasses that encrypt every attribute at the moment they are set. Even if someone did get in the DB, they would find it full of gibberish.
TechZen
I have to disagree with this answer. PLists and raw SQLite are a bad choice for persisting data. I have elaborated in my answer.
Marcus S. Zarra
+2  A: 

I have to disagree on TechZen's list. Number 3 is only a right answer if you are dealing with a legacy SQLite database. There is never a reason to choose raw sqlite over Core Data. Core Data will perform better in nearly every situation and will reduce the amount of code you have to write by a significant amount.

In addition, I would caution against using plists. They are expensive to read and write and a Core Data database will outperform them in nearly every situation.

As for using Core Data, you should always use a SQLite back-end (XML is not available on iOS) except in the most extreme circumstances.

In short, if you are saving a single value, store it in NSUserDefaults.

Otherwise use Core Data.

Update

There is one SINGLE thing that cannot be done with Core Data more performant than raw SQLite currently. That is the ability to update a single column's values across tens of thousands of rows. That is because to modify a row, Core Data loads that row into memory and then writes it back out again.

For every other situation you are going to gain better performance with Core Data than you are writing your own accessors, objects and dealing with the memory and lifecycles thereof.

Core Data will outperform any data accessors that you are going to write yourself and it is going to handle writing to and reading from the underlying file in a better manner than you are. Why re-invent the wheel?

Marcus S. Zarra
Thanks to all, for giving me your expert advise.I know that i can use SQLite directly or via Core Data.But,i still have some confusion about the performance of SQLite directly or via Core Data. Please let me know : what will be the difference between SQLite as back-end with Core Data and using SQLite directly using its APIs. I know that if there is huge amount of data in the DB, we can easily filter the records by SQL Query. What about Core Data?Can we fetch records based on certain criteria without fetch whole table?
AmitSri