I spent some time to research on the correct/recommended way to save using MagicalRecord, and felt a need to write this post.

It is relevant as of March 2013, using version 2.2 of MagicalRecord.

Tutorials out there

I wrote this because even tutorials eg from Ray Wenderlich (2014 Feb) didn’t use the recommended methods.

Or tutorials eg from Yannick Loriot (2012 Mar) are outdated.

Official methods

And unfortunately, the ‘official document’ on saving explains more on the recent changes to saving. That is least helpful.

Though if you dig further into threading, you will find a better and safer way to save.

And that is using [MagicalRecord saveWithBlock:].

What the author says

On StackOverflow, he said:

don’t use [NSManagedObjectContext save:]

On his blog, he explained why.

The code

Finally, here is the code to update an entity.

Poo is my NSManagedObject. Replace it with your own model.

    Poo *poo = [Poo MR_findFirst];
    // Update the entity in the block of saveWithBlock:
    [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
        Poo *localPoo = [poo MR_inContext:localContext];
        localPoo.someProperty = "awesome";
        // That's all to updating

Or if you want to delete the entity, use [localPoo deleteEntity] in the block.

On threading

Note that the block will be run in a background thread, not the main thread.

So if you want to do some UI updating, you should use saveWithBlock:completion: method.

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
    // This block runs in background thread
} completion:^(BOOL success, NSError *error) {
    // This block runs in main thread

Alternatively, you can use saveWithBlockAndWait: method.

    [MagicalRecord saveWithBlockAndWait:^(BOOL success, NSError *error) {
        // Any updating or deletion will be on main thread

Hopes this helps you!




Back to Home