Skip to content

Save And Update Entities

kevindelord edited this page Jun 28, 2016 · 6 revisions

Asynchronous Save

As explained earlier, when you want to create, update or delete entities, you need a saving context.

You cannot use an entity fetched from the default context into the new one. You need to fetch it again from the current context using entityInContext

Because the saving block in executed on another thread using another context, you need to retrieve the entities you want to use and/or update.

// Initial entity fetched from the current context.
let mySuperPlane = Plane.MR_findFirst()

DKDBManager.saveWithBlock { (savingContext: NSManagedObjectContext) in
	// Executed on background thread
	// Fetch again the `plane` entity from the new (saving) context.
	let localPlane = mySuperPlane.entityInContext(savingContext)
	// Update the attributes
	localPlane?.origin = "Tokyo"
	localPlane?.destination = "London"
}

At the end of this block, all performed operations will be saved ( or 'merged' ) into the Default Context and usable on the main thread.

Asynchronous Save With Completion

To perform an action after this save block is completed, you can fill in a completion block:

DKDBManager.saveWithBlock({ (savingContext: NSManagedObjectContext) in
	// Executed on background thread
	var localPlane = self.availablePlane.entityInContext(savingContext)
	localPlane?.origin = "Tokyo"
	localPlane?.destination = "London"

}, completion: { (didSave: Bool, error: NSError?) in
	// Executed on main thread
	self.tableView.reloadData()
})

As the completion block is called on the main thread, it is safe to trigger UI updates.

Synchronous Save

It is also possible to synchronously executes and saves modifications into the persistent store.

Be careful when performing saving operations on the main thread, it could slow down your application.

Nonetheless, this is very useful when you're managing your own threads/queues and need a serial call to create or change data.

DKDBManager.saveWithBlockAndWait { (savingContext: NSManagedObjectContext) in
	// Executed on main thread
	var localPlane = self.availablePlane.entityInContext(savingContext)
	localPlane?.origin = "Tokyo"
	localPlane?.destination = "London"
}
self.tableView.reloadData()

Make it small

It is highly recommended to only save small amount of changes to the persistent store.

From the MagicalRecord documentation:

Break the task down into smaller saves: Tasks like importing large amounts of data should always be broken down into smaller chunks. There's no one-size-fits all rule for how much data you should be saving in one go, so you'll need to measure your application's performance using a tool like Apple's Instruments and tune appropriately.

Long running process

If you need to perform changes that will take a while to save into the persistent store, refer yourself to this documentation.