ixx
ixx

Reputation: 32273

What does NSManagedObjectContext save do in terms of SQLite?

I'm porting some iOS persistence functionality to Android and trying to understand save(), in order to replicate the functionality in Android (pure SQLite).

Documentation says:

save: Attempts to commit unsaved changes to registered objects to the receiver’s parent store.

Doesn't help a lot.

I know that iOS uses SQLite so this has to translate to SQLite somehow.

Looks like save is an upsert - will insert the data if not there yet, and otherwise update.

If this is true (also if not, if the question is still valid) - how is determined which row to update? I don't see how to add unique in xcode, so if I have e.g:

id | name  | price    
1  | apple | 2.0    
2  | lemon | 1.0

with "id" being the internal row id,

and I get new model data "lemon" -> 3.0, when I update the moc, how does the database know that it has to update this row?:

2  | lemon | 1.0

In SQlite I would add a unique on the name, but I don't know how it's implemented in iOS.

I'm not an iOS dev, sorry for possibly super -ignorant or -strange question.

Thanks.

Upvotes: 1

Views: 618

Answers (3)

Chris
Chris

Reputation: 1673

It is really difficult to discuss Core Data in terms of databases because it is not a database. It uses one to persist data but that is just about it.

Looks like save is an upsert - will insert the data if not there yet, and otherwise update.

An NSManagedObjectContext is the current state of not just one object (or row in database terms) but multiple. So when you ask the NSManagedObjectContext to 'save' it is saving the state of all the objects in the context. If an object is new, it will be the equivalent of an insert. If the object already exists, it will be the equivalent of an update. However, if at some point an object is deleted, the 'save' method will also remove the object from the SQLite database. The 'save' method specifically saves the state of the NSManagedObjectContext.

If this is true (also if not, if the question is still valid) - how is determined which row to update? I don't see how to add unique in xcode

That is because Core Data handles the unique identity of objects. There is no default 'id' column to place a unique identifier. However, you can create an attribute (i.e. column/field) to hold a unique identifier if the database will be persisted across many devices, which I personally had to do at one time since the 'objectID' is not practical to use. In Android, you will have to maintain the unique identity of each row yourself unless you opt to use auto incrementation.

when I update the moc, how does the database know that it has to update this row?

At one point or another, you ask the NSManagedObjectContext to insert a new "Entity" (i.e. table):

NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:@"EntityName" inManagedObjectContext:managedObjectContext];

To update an entity, you could retrieve it by using:

NSManagedObject *managedObject = [managedObjectContext objectWithID:managedObject.objectID];

Make any adjustments and then 'save' the NSManagedObjectContext. The objectID is its unique identifier that was automatically assigned when inserted. Core Data handles the boiler plate code of inserting and updating rows so you end up with an abstract version as seen in the examples. If you save a few NSManagedObjects and open the SQLite file, you will find that it is very similar to any other database, other than a few Core Data specific fields that is uses for management.

I would suggest creating a new Master Detail Application project, run it in the simulator, save a couple entries, and open the SQLite file. You can find it in

/Users/<username>/Library/Application Support/iPhone Simulator/<iOS Version>/Applications/<Application UDID>/Documents/

Opening the SQLite file will show you that the database Core Data maintains is very similar to any other SQLite database and may help out with understanding the processes.

Upvotes: 1

Scott Berrevoets
Scott Berrevoets

Reputation: 16946

I don't know the following to be true, but I think I'm not far off.

An NSManagedObjectContext has a reference to objects (NSManagedObject) that are composed using the data from the SQLite database. These objects all have the objectID property, which is a unique identifier to the row in the SQLite database allowing you to uniquely, even between contexts, identify an object/row. When you change an object's property, this doesn't actually change anything in the database. The context knows about the changes, and when you call save:, it will go to the database and update all the records.

This is always an UPDATE, as you have to call -[NSEntityDescription insertNewObjectForEntityForName:InManagedObjectContext] to get a reference to an object. At that point, a record is already inserted and it is given an objectID.

Upvotes: 1

Eric Qian
Eric Qian

Reputation: 2256

NSManagedObjectContext is kind of a representation of the data model. It is from the framework called CoreData. By using CoreData, we do not manipulate the SQLite database directly. Which means we do not write any SQL queries, we just do all the update, insert or delete on NSManagedObjectContext. And when we call save(), NSManagedObjectContext will tell the database which row was updated, which row was deleted or which row was inserted. And here is another question which might help you to understand more about NSManagedObjectContext.

Upvotes: 0

Related Questions