When should I use the various storage mechanisms in iOS? - ios

I thought this would be covered already, but my search returned nothing of relevance.
I am aware that there is NSUserDefaults, Core Data, object archiving, raw SQLite, plists, and of course, storage by web servers. What is unclear and somewhat hazy to a beginner is when to employ each of these various tools.
The usages of web servers vs Core Data is obvious, but what about NSUserDefaults vs plists?
Core Data vs object archiving? A simple breakdown of use cases would really help me understand why there are so many options for storage in iOS.

I try to write a quick and simple list of common use cases, because as #rmaddy says this answer could fill a book chapter:
NSUserDefaults: stores simple user preferences, nothing too complex or secure. If your app has a setting page with a few switches, you could save the data here.
Keychain (see SSKeychain for a great wrapper): used to store sensitive data, like credentials.
PLists: used to store larger structured data (but not huge): it is a really flexible format and can be used in a great number of scenarios. Some examples are:
User generated content storage: a simple list of Geopoint that will be shown by a map or list.
Provide simple initial data to your app: in this case the plist will be included in the NSBundle, instead of being generated by user and filled by user data.
Separate the data needed for a
particular module of your application from other data. For example,
the data needed to build a step-by-step startup tutorial, where each step is similar to the others but just needs different data. Hard-coding this data would easily fill your code, so you could be a better developer and use plists to store the data and read from them instead.
You are writing a library or framework that could be configured in some
way by the developer that uses it.
Object archiving could be useful to serialize more complex objects, maybe full of binary data, that can't (or that you don't want to) be mapped on simpler structures like plists.
Core Data is powerful, can be backed by different persistent stores (SQLite is just one of them, but you can also choose XML files or you can even write your own format!), and gives relationships between elements. It is complex and provides many features useful for the development, like KVO and contexts. You should use it for large data sets of many correlated records, that could be user generated or provided by a server.
Raw SQLite is useful when you need really, really fast access to a relational
data source (Core Data introduces some overhead), or if you need to support the same SQLite format across multiple platforms (you should never mess with CoreData inner SQLite: it uses its own format, so you can't just "import" an existing SQLite in CoreData). For example, for a project I worked for, a webservice provided me some large SQLite instead of jsons or xmls: some of this SQLite were imported to CoreData (operation that could take a while, depending on the source size), because I needed all the features of it, while other SQLites were read directly for a really fast access.
Webserver storage well it should be obvious: if you need to store data to a server it is because the device shouldn't be the only owner of that data. But if you just need to synchronize the same App across different iOS devices (or even with a Mac-ported version of the App) you could also look at iCloud storage, obviously.

Related

How to decide what to use [Sqlite, Realm, CoreData, User-default, JSON file] to store data iOS?

After searching everywhere I found there is no properer comparison between SQLite, Realm, CoreData, UserDefaults, and JSON file.
You can find pros and cons easily but it's hard to know what to use.
I know the decision is totally dependent on the requirements. But still there must be a way to make decision.
Assuming the following cases, which options are best for individual and why?
Saving user watched history [Huge amount of data, Only insert, and delete operation]
Saving contact numbers [Max 1000 numbers, Need fast fetch, and continuous operation]
Saving simple GET API request [Use for caching]
Note: I am not talking about storing sensitive information here.
Feel free to add/update more relevant cases.
The most part of data storage implementation is just SQLite wrappers. The most common iOS implementations are SQLite, ORM, CoreData, Realm, Keychain.
Another part of implementations is just a simple text. For example, UserDefaults is just an XML file which you can edit using simple iOS API. But SQLite wrappers are more useful for performance reasons when you work with more than dozens of elements.
So, what about SQLite wrappers?
You can use Keychain but it has several disadvantages: this is not a thread-safe, you can obtain the data only at allowed moments of application, from time to time it returns incorrect results for existed elements. This is useful for passwords, no more.
CoreData has native API, but it has got memory leaks disadvantages, complicated API, this is not a thread-safe database, not a good performance.
SQLite. First of all, you can use the native C library with 11KB dependency. Disadvantages: Old-style C API, raw SQL queries.
SQLite Swift wrapper. In this case, you have to use third-party libraries. But well perform.
Realm. This is really well-performed and easy to use. But it has got a disadvantage for thread-safe. The difference between ORM and Realm is that the objects in the Realm are not stored as an obvious table, it has its own magic how to convert the data into table representation.
Firebase database. I didn't use this library in the production. It has got online implementation as a primary feature. I'm not sure is it correct using a primary internal database.
What about the summary?
SQLite (Wrapper, pure C) and Realm in our test have nearly the same performance. CoreData isn't good enough.
SQLite wrapper and Realm have enough good API.
The only SQLite wrapper is really thread-safe.
Available Options to save data in iOS.
User Default: Quicky persists a small amount of data.
Codable (NSCoder): for saving the custom object.
Keychain: Small bit of data securely.
SQLite: Persist large data but require query operation.
Core Data: Object-Oriented Database.
Realm: Faster and easier database solution.
CoreData, Sqlite & Realm store plain text in-store if you don't tell it to encrypt, you can use encryption in all to make it secure.
Saving user-watched history [Huge amount of data, Only insert, and delete operation] Coredata & Realm should be used.
Saving contact numbers [Max 1000 numbers, Need fast fetch, and continuous operation] Coredata & Realm should be used.
Saving simple GET API request [Use for caching] Codable, Coredata & Realm should be used. The response can be used for
offline storage.
Data storage and caching very important topic. Choosing way to store data can rely on whole app design.
Caching:
NSURLCache: Simple option to configure cache of desired size. Works good for caching data that does not need any post processing (JSON, Image Requests).
let URLCache = NSURLCache(memoryCapacity: 4 * 1024 * 1024, diskCapacity: 20 * 1024 * 1024, diskPath: nil)
NSURLCache.setSharedURLCache(URLCache)
File Cache: If you need to post process data somehow (like round corners on images, build own data structure from JSON) file cache can be an option. Images can be saved as plain files, for data objects you can use NSCoding protocol.
Database: For fully working offline mode better to use database.
Persistence:
NSUserDefaults: Small pieces of data. Not secure, no sync.
SQLite: Memory efficient and cross-platform. Usually not a best option. Useful when you want to share existed cross-platform database in app.
Core Data: Good option when you need complex queries and complex relations between objects. Have basic migration support and visual code editor (with code generator). Probably it should be default option unless you need: syncing or cross-platform.
YapDatabase: Faster than CoreData. Have iCloud sync.
Realm: Some article says that it is faster than CoreData and thread safe. Have a lot of options and some of them are paid (like Sync). May be a good alternative for CoreData.
Firebase: Cloud platform. Have offline mode, but paid.
CouchBase: Free Sync. No migrations needed as very flexible schema.
In a conclusion:
Simple records: UserDefaults, NSCoding
Local data storage, complicated records: CoreData (Yap, Realm)
Syncronization: CouchDB, Yap (iCloud), CoreData (iCloud-), Realm (Paid), Firebase (Paid)
Speed: Yap, Realm
Patform or Cloud Based: Firebase, Parse
Cross-platform: Realm, CouchDB, MongoDB, Firebase
My personal opinion is the following:
Core Data: Good support from Apple, native, visual editor, good performance for most of the use cases, but with a quite uncomfortable API in my opinion.
Realm: Simple API, incredible speed, easy migrations. But personally, the issue of threads bothers me a lot. Working with threads using Realm is difficult and annoying. For the rest, it seems great to me. Another thing, it also adds some size to the APP but it's worth it.
If you ask me personally, I love realm, I've also used Core Data a lot, but ended up sticking with Realm.

Usage of Core Data other than a Database

i am new to this Core data. When i search for tutorials, I'm seeing this sentence Core Data is not a database everywhere on the internet.
If it is not a database, why are we using it as a database?
For what purpose Core Data is initially created?
Is there any other way Core Data was used before/will be used in
future (Other than as a DB)?
Sorry for my English.
Thanks for the time.. (:
Actually Core Data is a bridge between the code and the underlying database (like SQLite or XML...). Core Data is not a database, but uses SQLite (or XML...) for persistence. The main purpose of Core Data is to manage memory objects and object graphs easily without having to do it manually through a SQLite library for instance. It is possible to use Core Data without persistence is you want (using In-Memory stores).
Here is the documentation : https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/index.html#//apple_ref/doc/uid/TP40001075-CH2-SW1
Bye!
If it is not a database, why are we using it as a database?
"We" are not necessarily doing so, depending on who you mean by "we". Core Data can be used in a database-like manner, keeping in mind the Core Data vs. SQL differences others have noted. But that's not the only possible use.
Statements that Core Data isn't a database are mostly intended to prevent people from thinking of Core Data in the same sense as SQL. That sort of thinking leads to badly designed data models, since the approach is different. It can be used as a database in the generic sense of the storing structured data but it's important to not assume that it works like other databases you may have used.
For what purpose Core Data is initially created?
Is there any other way Core Data was used before/will be used in future (Other than as a DB)?
Core Data was created to fill what might have been perceived as a missing piece in Apple's frameworks. They generally take the MVC approach. There were classes to help in designing and implementing views (in these pre-iOS days that meant AppKit) and with controller classes (for example NSArrayController, also an OS X class). But model support was limited to NSCoding, which required a lot of repetitive code. Custom solutions also had trouble scaling to large amounts of data-- for example NSCoding doesn't help you load only part of a large document graph, because it recursively works its way through the entire object hierarchy.
Core Data was added with the purpose of making it easier to design and implement the model layer of an app. It's no accident that the document you edit to design the data is called a data model and not a schema.
The idea was (and is) that you could
Design your data model visually in Xcode
Create and use instances of your model objects
Read and save those objects in a file
...all without ever needing to write your own code to figure out how to convert your model objects to and from something that could be written into a file, or with the mechanics of opening a file, reading/writing it, and saving it. You'd just create objects as needed and then call save on NSManagedObjectContext. The small bit of code that was concerned with locating and opening the file was all pretty much the same in any app, so while it was still required it was mostly no longer the app developer's concern (and in iOS 10, NSPersistentContainer eliminates even this). You'd also get the benefit of only needing to load the parts of your object graph that you currently needed instead of loading everything every time.
As you've noticed, in practice Core Data is commonly used more or less like a database, and it works for that. But it's not designed to be limited to such uses.
Yes it is true , Core data is not a Database, though internally it saves data using sqlite. We use Coredata for persistent data which means we should be able to save the data and use it even after closing and reopening the app. There are various ways to store data like Sqlite,Plist,UserDefaults and CoreData. Coredata does not maintain any relations like SQlite. It means there are no keys like primary and foreign etc. Coredata allows you to deal with data in Object Oriented Approach. You can easily work with data operations even you don't have knowledge about DB queries.

Core Data for preloaded information

im learning about core data at the moment, I can see its benefits for apps like a phonebook etc, however is core data good if your app is to contain preloaded data. For example the players of an American football team. I was using MESASqlite and manually entering the ino and then copying and pasting it into xcode to have all the players preloaded in my app.
Basically, I hear core data is not a database (according to the Apple documentation) so im a little confused.
Using CoreData as a read-only pre-loaded data-store is very possible. In fact, CoreData's faulting mechanism may well work in your favour to keep runtime memory consumption low if the dataset is large. Using CoreData is almost certainly easier than fetching sub-sets of records as required from an SQLite database with SQL. CoreData also provides a solution for versioning, and model version updates.
To do this, you use an SQLite backing store and will need to write a tool to populate the initial model. Note that whilst it's just about feasible to use an SQLite database table editor to modify individual fields, you definitely can't create or delete rows using one.
In terms of a tool for populating the initial model, it makes a lot of sense to make this a MacOSX console or Cocoa application and run it as part of the application's build process. You include the SQLite database as a binary resource in your iOS application.
Building a graphical editing tool is actually far easier in MacOSX than iOS because of the extra KVO bindings on many controls provided by the cocoa framework - for instance, in NSTableView.
Alternatively, you can easily convert data from an existing format such as CSV or XML.
I almost always use Core Data, for pre-populated or empty databases. If you have to handle persisted data, you can either use .plist or database (mostly sqlite) files. The difference is that if you use .plist files, you load the data into NSDictionary objects. On the other hand, if you use Core Data, the persisted information is loaded into "managed" objects, wich are easier to work with. You have several advantages using Core Data (manage several contexts, data model editor, caching, etc.)
If you are not familiar with Core Data you should give it a try
Core Data may not truly be a database, but it holds a number of common features with SQLite databases.
Yes, Core Data is a good option. You would generally use an SQLite store to hold the data in your app. You can also write some code or a desktop app which will allow you to edit the preload database. You'd then copy the preload database to your Xcode project.
If you already have a solution using MESASqlite and everything works then there isn't a particular reason to change.
Basically, I hear core data is not a database (according to the Apple
documentation) so im a little confused.
Core Data is an object persistence framework: you put objects into a store, and you can get them back out later. So it's like a database, and it can use a database for the actual storage, but if you're thinking about it in terms of tables and rows instead of object graphs you should maybe consider just using SQLite yourself. Working with objects lets you build the smarts for manipulating your data into your classes, and the objects you pull out of a data store will have those behaviors.
is core data good if your app is to contain preloaded data.
Sure -- it's great for stuff like that. In fact, it's not uncommon to write a simple Mac program that takes data from somewhere else and adds it to a Core Data store using the same model you've created for your iOS app. You can build that data store into your iOS app along with the model, and it'll just work.

Data model persistence considerations in iOS

I've been working with sqlite database in my iOS app for data persistence, and I'm now trying to decide if it is worth to learn Core Data. I've been reading some documentation and posts regarding its pros and cons, but I find that deciding when to use Core Data or Sqlite is not so clear (for example, Core Data VS Sqlite or FMDB…?).
I need some guidance to know if I should learn and use Core Data, or using Sqlite is enough for me:
Already having sqlite scripts, is it possible to build a Core Data model from data in sqlite database? Afaik, (correct me if I'm wrong) you can use sqlite to persist Core Data objects, but is it possible to operate in reverse?
Is it appropiate Core Data for handling several users data? I need to take into account that different users could log in into the app in the same device.
Thanks in advance
Core Data is a wonderful framework but while it generally uses SQLite behind the scenes, you shouldn't think of Core Data as a database engine, but rather more of an object persistence framework. If you've got a lot of SQL code (especially bulk updates and the like), it might not be worth converting to Core Data. But Core Data has lots of wonderful performance optimizations, iCloud integration, etc., so it's worth examining in greater detail.
If you want background on Core Data, I'd suggest the Apple video Working with Core Data.
If you just want to simplify your SQLite code, check out FMDB.
In answer to your questions:
Already having sqlite scripts, is it possible to build a Core Data model from data in sqlite database? Afaik, (correct me if I'm wrong) you can use sqlite to persist Core Data objects, but is it possible to operate in reverse?
You generally have to redefine your Core Data model. It cannot just open your existing SQLite database (though once you define your model, you could write code to transfer the data from SQLite to Core Data).
Is it appropiate Core Data for handling several users data? I need to take into account that different users could log in into the app in the same device.
Yes, you could. You'd have to define your model to handle this manually, though (e.g. add a user identifier field and manually code predicates/filters results accordingly, much like you'd have to do in SQLite).
AppsDev,
Only you can judge whether to use Core Data or to stick with SQLite. As you've referenced my answer above, you know my view -- use Core Data. Let me put it in your context.
The big win is the family of abstractions that come with Core Data and how they map onto the Objective-C object model. This is something you have to handle manually from a SQLite application. (Can you do it? Yes. You will, though, most likely make a custom interface that is tuned to your SQL schema. It will have little reusability. This is a long term problem.)
As to the question of predicates versus SQL queries, this is a difference in world view. That said, as predicates can be applied to both NSSets and NSArrays, they have a utility beyond that required by Core Data. Knowing how to use predicates will be of value. For example, you could easily perform a query to get a collection of records and then use predicates to filter them, say for the search of a table view.
Everyone needs to pick when they are ready to embrace a specific pattern. SQL experts, unsurprisingly, like to stick with what they know. Dynamic language aficionados will choose differently. For iOS/OS X, embracing the dynamic language path will have ever increasing value to you as a developer.
Hence, my recommendation remains: use Core Data.
Andrew

Should I be using Core Data?

I have developed an app that downloads the whole dataset into an array of objects. Should I be using core data to store the data? Aside from having some off-line data at hand for the user, are there any other advantages?
Thanks,
Steve
It's difficult to say with so little information. But if you need to store and access a bunch of data in iOS, Core Data is usually a good option.
It's obviously more complex than just storing the data in files (an array/dictionary can write its contents to disk) but you get a lot of other stuff for "free." Nice things include NSFetchResultController which means you can push your data into a table view with very little code. It makes things like undo and transactions easier.
Another option is using SQLite directly. If you know SQL and your data structure doesn't easily fit into an object graph (for whatever reason) or you want more control than Core Data can give you, it can be a good option.

Resources