IOS 6 What is the standard way to deal with preserving the background of managed objects (in 2013)?

Last year, I used RestKit 0.10 to seamlessly download and save basic data objects in the background. However, when I tried to use restkit in 2013, I noticed that they pulled out the ActiveRecord template that I relied on to distract all the troubles of saving the background.

I found that the ActiveRecord template exists in the MagicalRecord structure, but most of the documentation I can find is for version 2.x, while my cocoapods install 3.x.

I spent the last 2 hours of searching and found many answers that are really outdated and no longer work for these new frameworks.

The question arises: what is the standard / easiest way to deal with saving basic data objects in the background using the frameworks available in 2013? . Should I try a different infrastructure?

+4
source share
1 answer

If you are not using any external library, such as Magical Record or RestKit, but simply downloading all the manual files, you can use the new NSManagedObjectContext APIs.

Now you can have contexts nested in parent-child relationships, and you can also tell each context about the execution of a block in its own thread. Therefore, my advice should have the following structure for your application:

1) Context save background. This will be the only context that saves and reads data directly to / from the database.

2) The context initiated in the main thread, which will become your access point for everything you need to do in the application, especially for updating the user interface. This context will be a child of the persistence context.

3) If necessary, you will create background contexts that perform work with background threads, for example. Downloading data from the network and serializing this data in instances of NSManagedObject. These contexts will be children of the main context.

4) Each time you call -[NSManagedObjectContext save:] in context, you must also call the same method on it parentContext. For this, you can have a convenience method in a category in NSManagedObjectContext that reads something like this:

 - (void)saveSelfAndParent { [self save:NULL]; [self.parentContext performBlock:^{ [self.parentContext saveSelfAndParent]; }]; } 

This is already a thread-safe configuration, and your changes will propagate the changes down to the database. Note that since the save context will not have a parent (and therefore self.parentContext will be zero), executeBlock: will not cause the application to crash.

Here is an example of what you need to do to create a new object, assuming you are starting background work with Grand Central Dispatch (GCD):

 dispatch_async(dispatch_async_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType]; context.parentContext = mainContext; // do some expensive job ... // initialize a new NSManagedObject instance using the information we calculated NSManagedObject *myObject = ...; // once we're done, let save the context [context saveSelfAndParent]; }); 

Note that we initialized the context with the concurrency private queue type (NSPrivateQueueConcurrencyType), which tells the context that it is a background context. It is very important!

It's all!:)

See the NSManagedObjectContext Reference Reference for more information.

+4
source

Source: https://habr.com/ru/post/1486660/


All Articles