Swift — 4 — Core Data — Part 7 — Concurrency

In context of core data, concurrency is the ability to work with the managed object in more than one managed object contexts.

There is a video at the bottom of the page do not forget to check it out.

Please support us by comment, like and share my facebook page.

In our core data journey so far we discussed about insert, update, delete, fetch, fetch result controller, unit testing etc.

At every point where ever we need managed object context, we just used persistentContainer.viewContext. So, This is the right time to explore more about managed object context.

There are two types of managed object contexts: main queue and private queue.

Main queue

  • By default persistent container’s view context is of type mainQueueConcurrencyType
  • Whenever we have accessed persistentContainer.viewContext that is by default of type mainQueueConcurrencyType.
  • The main context MUST be used to display managed object on user interface.
  • Main context should not be used for long running task like fetching records, batch updates, insert a lot of records in core data.

Code:

or we can access it from persistentContainer

Private queue

Specifies that the managed object context will be associated with a private dispatch queue.

In general, avoid doing data processing on the main queue that is not user-related. Data processing can be CPU-intensive, and if it is performed on the main queue, it can result in unresponsiveness in the user interface. If your application will be processing data, such as importing data into Core Data from JSON, create a private queue context and perform the import on the private context. Another example can be if you want to fetch data from core date use private context.

Code:

or we can access background context from persistentContainer

or we can ask persistent container to perform some task in background.

NOTE : Always access main managed  object context to update UI.

Let’s code now:

Please download starter project from here.

Launch project and open CoreDataManager.swift file. Add completion typealias after imports

Now copy paste below lazy var for backgroundContext to make sure to create only one background context. Persistent container provides a method named newBackgroundContext() to create a background context.

Now copy and paste below method:

We have .perform method to write long running task (fetch)in background context. And finally using completion handler to callback.

Now open ViewController.swift file and replace fetchAllPersons() method with below method:

  1. We are calling fetchAllEntities method, passing parameter as string.
  2. We will get arrPeople which will contain array of managed objects , Person in our case.
  3. As we need to use main context for our UI update, we will get Person objects based  on their object id. It is one of the most important aspects to note that managed objects should not be passed from one context to other instead their object id should be used.
  4. Prepare array for table view datasource.
  5. Reload table (update user interface) on main thread.

Will you ever pass managedObject from one context to another context?

No, NSManagedObject instances are not intended to be passed between queues. Doing so can result in corruption of the data and termination of the application. When it is necessary to hand off a managed object reference from one queue to another, it must be done through NSManagedObjectID instances.

You retrieve the managed object ID of a managed object by calling the objectID method on the NSManagedObject instance.

According to the Core Data concurrency rule, each thread must have its own managed object context. This is because NSManagedObjectContextand NSManagedObject, two most fundamental objects in Core Data, are not thread safe. They shouldn’t be initialized in one thread and accessed from a different thread.

Other way of using back ground context:

most things remains same with this approach also. Only change is:

The benefit I see is persistent container will provide you these method already set up, just do you long running in background and update main queue. To test this method you only need to change

in method

to

That’s it.

Final core data manager should look like this, i have added two methods at the bottom of file:

That’s it for now.

Run and debug with me to see how newBackgroundContext is working:

Please support us by comment, like and share my facebook page.

Run and debug with me to see how persistentContainer.performBackgroundTask is working:

Conclusions 🙂

  • Always perform UI updates on main queue.
  • Use managed object id’s to pass them around in other context.
  • Managed objects are bound to their context (main or private)
  • Perform long running core data operations in background contexts.
  • And yes we can have more than one managed object contexts :).

In further tutorials will discuss about managed object notifications, parent child context and sibling contexts…

Happy Coding!

Please support us by comment, like and share my facebook page.

Here is the source code!

 

One thought on “Swift — 4 — Core Data — Part 7 — Concurrency”

Leave a Reply

Your email address will not be published. Required fields are marked *