Updated core data concurrency documentation? - ios

The only (and most recent) results I'm finding about best practices are here: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/Articles/cdConcurrency.html
However, the very top of the page says,
"Important: Best practices for concurrency with Core Data have changed dramatically since this document was written; please note that this chapter does not represent current recommendations."
Where can I find more current documentation for concurrency with core data?

The best discussion is now under 'Concurrency' within the NSManagedObjectContext documentation.
My summary:
Thread confinement is still required. The big changes introduced by iOS 5/OS X v10.7 were that contexts can now have other contexts as parents and can manage their own serial queues.
Changes are automatically migrated from children to parent upon a save. That's now what save means. Only if your parent is the persistent store are you actually committing to disk.
So all that stuff about synchronising by notifications is what Apple doesn't want you to follow. All of those mechanisms are still available but Apple has pulled the most common patterns directly into the framework.

The Core Data Programming Guide has been updated for iOS 9/OS X El Capitan. See https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Conceptual/CoreData/Concurrency.html.
I also found WWDC 2014 session 225 What's new in Core Data (at 22:50) very helpful in understanding both current and historic concurrency methods.

Thread confinement has been obsoleted. You can see this in the header for NSManagedObjectContext:
NSConfinementConcurrencyType = 0x00, /* this option is obsolete and not recommended for new code. */
When a context is created with -init, it calls the initializer -initWithConcurrencyType: with the argument NSConfinementConcurrencyType. This is the threading model described in the Core Data Programming Guide section on concurrency, that has been obsolete and not recommended for some time. In the words of one Core Data engineer "It just didn't work.".
Unfortunately that Core Data Programming Guide has not been updated to describe the current recommended best practices for concurrency and other advancements.
But hey, at least it's not telling you to use locking!
The Incremental Store Programming Guide has been updated recently. It describes how to implement an NSIncrementalStore, and in doing so does a very good job of explaining some of Core Data's internals. For example, it describes what a fault is and how faults are fired far better than the Core Data programming guide ever did. The Core Data release notes for the past several years have included some updated information about best practices, and there are several tech notes that are relevant to Core Data.
The best information in the last several years has been the yearly "What's New In Core Data" sessions at WWDC. For concurrency, you should check out these WWDC sessions:
WWDC 2011 What's new in Core Data on MacOS X. The MacOS X session was a little more detailed than the iOS session.
and
WWDC 2012 Core Data Best Practices
I would encourage you to use the "Feedback" button on the Core Data Programming Guide pages, or file a radar bug asking for the documentation to be updated.

The guide that I've been following is here: http://www.cocoanetics.com/2012/07/multi-context-coredata/
Even though it was written in 2012 it still seems to match what i've seen currently being used. It helps you set up a main parent context with NSMainQueueConcurrencyType, multiple background contexts with NSPrivateQueueConcurrencyType, and also has a background writer context that has the persistent store.
Xcode 6 and Yosemite also seem to have an improvement in core data debugging: http://oleb.net/blog/2014/06/core-data-concurrency-debugging/. This was useful in understanding how to use performBlock at the right places.

Related

Plain Core Data vs Core Data + Magical Record

I'm planning a way to persist data for an iOS (swift) app. From reading a bunch of articles about persistance on iOS, it seems Core Data is a really well supported way to do that. A bunch of libraries/tools are built around it, one popular combination seems to be MoGenerator + MagicalRecord + Core Data.
As MagicalRecord provides some kind of Active Record functionality, it seems it could be "easy" to accidentally break things. I've been told it could happen that users would have to reinstall their app to recover from such failures.
So question: is it feasible to use just plain Core Data instead of MoGenerator + MagicalRecord + Core Data? Or is this so low level, that it only makes to use raw Core Data for big teams? Can the pros/cons be compared to those of plain SQL vs ORM?
I would strongly recommend to NOT use MR or Mogenerator until you know enough about Core Data to know WHY to use them.
Magical Record really can seem like magic if you don't understand what it is doing under the hood. And to use Core Data without a good understanding of the basic framework is to invite problems that you will never get to the bottom of. There are Core Data traps that you are going to need to understand, whatever tool you use.
CD is not really low-level compared with MR: but is more verbose (MR is saving you a lot of boilerplate). However I would recommend spending a bit of time with a decent book like Learning Core Data for iOS by Tim Roadley. When you have worked through that, you may find - as codeFi suggests - that you have built yourself a core data engine that does enough for you so that the addition of Magical Record unnecessary.
Another problem with going for MR is that the stable release, 2.2, is two years old. V2.3 is still in beta, and going forwards the focus is on 3.0. If you use the stable release, and find issues with it, they won't get fixed. If/when v3.0 is ready, the interface may be completely different anyway.

Integrating a traditional Core Data stack with iCloud: Conflict management

I'm developing an iOS application, and I've hit a brick wall with conflict management in Core Data. So far, I've built a Core Data stack, whose entities sync with iCloud, without much trouble.
But conflict management remains an enormous problem.
Apple's UIManagedDocument exposes a public interface that's been designed to make it easy for developers to handle document-version conflicts. In my application, the documents (NSManagedObjects in my Core Data stack) need to have relationships with other NSManagedObjects--as far as I can tell, that means I need to use a traditional Core Data stack, rather than UIManagedDocument. Is that true?
As far as I can tell, the only way to handle conflict management in a "normal" Core Data stack is to subclass NSMergePolicy. Is that correct?
If the answers to (1) and (2) are YES, then I need to subclass NSMergePolicy so that:
If the user edits document A on both device X and device Y while iCloud is unavailable (e.g. because the devices are both in Airplane mode), then the NSMergePolicy subclass needs to save both of these versions of document A to the iCloud store. This is how Apple's Notes app works.
Unfortunately, I've found almost no information on how to properly subclass NSMergePolicy for such a task. Apple's documentation has very little to say on the topic. Could you explain how one might approach the task, or direct me toward an in-depth tutorial/sample project?
Is there a better/easier/simpler way than subclassing NSMergePolicy?
I really appreciate your help. I'm hesitant to try anything before I'm sure what the right approach would be.
Thanks,
Robert

Core data multithreading with children contexts

I have just began learning Core data. When it comes to multithreading, some blogs say that in this case we should use children contexts (by creating a context and setting its parent) and just invoke the performBlock: method. However some other blogs say that we should avoid this approach since it has introduced many bugs.
I have just began developing an application that manipulates a large data base and the project manager voted for Core data (instead of SQLLite).
Could any one please give me some directions. Should i use the children contexts strategy (introduced since iOS 5) or is there a better way to perform multithreading with Core Data ?
Thanks.
Should i use the children contexts strategy (introduced since iOS 5)
or is there a better way to perform multithreading with Core Data ?
In addition to the concept you mentioned, Managed Object Contexts have built-in concurrency support without parent contexts (see https://developer.apple.com/library/ios/releasenotes/DataManagement/RN-CoreData/index.html).
If you create one using initWithConcurrencyType:, you can use performBlock: and performBlockAndWait: and the threading will be handled for you, assuming you follow the basic patterns outlined in the link above. The parent/child context approach can help you with synchronization.
There's also an NSOperation-based approach outlined here: http://www.objc.io/issue-2/common-background-practices.html. I personally wouldn't use it, because the built-in APIs are sufficient, but the article is very well written and should give you a good idea of what's going on.
How you implement this depends on the needs of your app.
some other blogs say that we should avoid this approach since it has
introduced many bugs.
I would ignore them, and focus on writing clean code for yourself. There are plenty of apps that use multithreading + Core Data without bugs.

Simple Concurrent Core Data

I've done a fair amount of research over the past few days, but I'm not sure what the current best practice is for concurrent Core Data. The most relevant post seems to be this blog post, but in light of this analysis about the performance of different concurrency methods, it seems that the modern way with parent contexts might not be the best. Also, this example from Apple doesn't implement the best practice mentioned in Apple's own concurrency guide that recommends NOT using the default NSConfinementConcurrencyType.
In light of all of this, what is the simplest and best way to implement concurrency with Core Data? All I need is a background thread the do some long writes to Core Data without hanging up the UI. Code examples are appreciated.
As always, it really depend on what you are trying to accomplish.
"long writes" will hang your UI no matter the architecture you implement.
A write operation lock the DB file in the OS level and the sqlite engine level (if you use this kind of store), all pending read operations will have to wait for the write to end before they complete.
One of the most used optimisation methods is segmenting the database "load" process with multiple save operations (you shouldn't mind as this happen in the background).
So, to answer the question:
The simplest way for you, would probably be to use the architecture described in the blog post you mentioned (parent-child hierarchy). if you notice that this cause to much "stutter" for your UI, try to optimise your data load process or try a different architecture.
use instruments to find "bottle necks" in your application execution.
CodeData has "quirks"/bugs in every architecture that I know, and you will find them gradually, depending on your use of it.
My recommendation is to go with the parent/child context pattern. In the light of the sparse details you give (e.g. number of records, total volume of data, latency of delivery, etc). this seems to be the most flexible and proven solution that can also accommodate very large datasets.
Contrary to other claims, you can have a smoothly operating UI regardless of how long the "writes" are to your database. Obviously, that is what background threads are for. The mechanism to keep the UI fluid is through so-called notifications about data change. You can react to these gracefully without disturbing the user experience.
Your remark about NSConfinementConcurrencyType is correct. As stated in your source, it is there for backward compatibility, so you can just forget about it. Obviously, for concurrency you want to use NSPrivateQueueConcurrencyType when creating your context.

Advanced concurrency in Core Data

Where can I find concrete examples of advanced CoreData concurrency? By advanced I mean operations on contexts and NSManagedObjects that run simultaneously on two or more threads and every thread can both read and change objects. Each objects saves contexts and listen for changes in another threads, everyone merges changes properly, nothing crashes, there are no inconsistency exceptions, everything is done as it should be.
I read official Apple document about Core Data concurrency, now I'm looking for code examples, tutorials, books, or at least some more detailed information on how to handle this type of scenario.
there is a really nice blog post from cocoanetics:
Multi Context Core Data
and i have created a github repo for the Async Saving Example:
Multi Context Core Data GitHub

Resources