James Dawson
James Dawson

Reputation: 948

sqlite or coredata for complex data structure on ios

I have quite a complex data structure I am going to use in an iPhone/Ipad app. After getting rid of a lot of un needed tables and flattened the data structure down as much as I can. – Ie if I have a call table and address table in the real structure, as I don’t need to update the address information at all I have extended the IOS call table to have the address info rather than linking the table – basically de-normalised as much as I can to reduce the table complexity.

All in all I still have 15 tables.

I can easily script the tables into SQLlite and have had a quick play with the SQLlite C API in IOS and have it working OK.

My question is – for a failry large data capture application with lots of related tables should I stick to my SQL Skills and use SQLite and the C API, or convert it all to coredata?

My main worries with coredata are a) the setup time – is there a way of creating a coredata data map from an existing database schema (SQL Server, SQLite or scripts) b) if I have a few thousand rows in one table (it’s a list of stock items that are used on jobs). My understanding is that coredata retrieves ALL of the items for that object, then filters them using predicates. Is this how it really how it works, or have I misunderstood? Is this efficient if it does behave like this? c) While I have flattened the structure as much as possible, there still could be a need for me to join 3 or 4 tables together – in core data is using the relationships like this as efficient?

I have no problem re-reading the coredata books and then applying it if it really is a better solution for this kind of scenario, it’s just all the books and examples I have read are 1 or 2 entities with a few attributes with a single relationship. My DB schema, and so my coredata data model would be much more complicated than this. One other consideration is – does core data offer any advantages over sqllite for consuming rest services or JSON to get data from the server and put transfer completion details back to the server?


please see my experiences below: in case anyone reads this post and wants to know my experience as a SQL Server/ASP.net guy....

i started using SQLite, i found that it was quick and easy enough to use. the API wasn't great, but being a SQL guy this didnt phase me at all.

i was able to script table structures from SQL Server easily with small mods to the generated scripts leaving me with my table structure in SQLite very quickly

I started out in asp.net with access, so I am no stranger to scripting and creating dynamic SQL Strings. I however no longer want to use this approach as I feel it's outdated, so although probably overkill as I was using SQLite to retrieve data, I wanted to put the data into a proper object. I wanted to create arrays of my objects and edit the attributes of my objects. it just makes more sense to me in objective C. In asp.net I still DO NOT make objects for my data, I use SQL Server stored procedures as I have a very complicated data structure, and want complete control over everything I query.

HOWEVER it takes AGES to create classes to wrap your tables in. In core data it's a single click to generate a class that represents your core data entity, so the trade off was spend time manually generating the coredata schema vs manually generating the classes to represent the data tables/entites/whatever you prefer to call them.

i chose core data here.

YOU WILL PROBABLY NEED TO USE CATEGORIES TO EXTEND THE GENERATED CLASSES, but this is actually really easy, and very cool,

one big advantage of coredata is the fetchedresults controller automatically displaying changes in a table view. as my app has 2 or 3 table views which are hierarchical - changing data in say view 2, then going back to a tableview, view 1 and seeing the updates made in view 1 without having manually reload the data was very very cool.

the predicates are OK. they make enough sense, bear in mind, whatever object you are fetching, you can transverse the relationships FROM THAT OBJECT - also quite cool, if a bit messy sometimes – it’s a totally backwards way of thinking from sql I felt. Once you are used to it, its easy enough and powerful enough. It’s just a bit weird at first

NSManaged objects (any objects you are storing in core data) and subclasss thereof have their own managedobjectcontext - ie self.managedObjectContext making is a breeze to explicitly save any changes ie:

self.name=@"james"
self.favouriteColour=@"blue"

NSError * error;
if ([self.managedObjectContext  save:&error]) {
    NSLog(@"saved");
}

which is MUCH cleaner than having to setup sqlite connections, commands and execute them, etc.

the core data API is a lot cleaner than the SQLite API (well it is c).

guess i'm a convert!

Upvotes: 4

Views: 2674

Answers (1)

Martin R
Martin R

Reputation: 539815

First of all (and you probably heard that before): Core Data is not a database. It is a "object graph manager with lifecycle, searching and persistence features" and this article describes the differences better than I can: http://www.cocoawithlove.com/2010/02/differences-between-core-data-and.html.

See also Use CoreData or SQLite on iPhone? and the links in there for more information that might help.

Now to your concrete questions:

a) the setup time – is there a way of creating a coredata data map from an existing database schema (SQL Server, SQLite or scripts)

No. You have to create a Core Data "model" first (using the Xcode model editor). A model consists of entities which have properties and relationships to other entities. Core Data has "persistent stores" which can be a SQLite file (but also an "in-memory store"). The schemas and tables used by Core Data are officially undocumented. You could try to create the SQLite Core Data store directly (the format is not too complicated), but the easiest way to migrate from SQLite to Core Data is probably to write your own code that reads the SQLite tables and creates the corresponding Core Data objects.

b) if I have a few thousand rows in one table (it’s a list of stock items that are used on jobs). My understanding is that coredata retrieves ALL of the items for that object, then filters them using predicates. Is this how it really how it works, or have I misunderstood? Is this efficient if it does behave like this?

Your understanding is not correct. Core Data uses "fetch requests" to fetch data, optionally filtered by a "predicate" and sorted by a "sort descriptor". For a SQLite-based store, the fetch request is translated to a SQL query and executed on the SQLite level. (This imposes restrictions on the possible predicates, and not all SQL queries are possible with a fetch request.) Only the fetched objects are loaded into memory.

c) While I have flattened the structure as much as possible, there still could be a need for me to join 3 or 4 tables together – in core data is using the relationships like this as efficient?

Yes.

... does core data offer any advantages over sqllite for consuming rest services or JSON to get data from the server and put transfer completion details back to the server?

Perhaps have a look at RestKit, which has Core Data support. But I am not familiar with that, so I cannot give more information on about this question.

Upvotes: 4

Related Questions