iOS 10 brings some welcome improvements to Core Data, including the all new NSPersistentContainer class. With this release, Apple has created a streamlined API that captures the most common uses of Core Data in iOS applications. In this episode we'll take a look at NSPersistentContainer, as well as the new code-generation capability in Xcode 8.
Episode Links Source Code What's new in Core Data in macOS 10.12, iOS 10.0, tvOS 10.0 and watchOS 3.0 NSPersistentContainer let container = NSPersistentContainer(name: "Episodes") container.loadPersistentStores { (storeDescription, error) in container.viewContext.automaticallyMergesChangesFromParent = true try! container.viewContext.setQueryGenerationFrom(.current) if let e = error { print("Error: \(e)") } else { print("Core data loaded: \(storeDescription)") } } Fetching Existing Records Generated models now produced strongly typed fetch requests: let fetchRequest: NSFetchRequest<Episode> = Episode.fetchRequest() let existingEpisodes = try! fetchRequest.execute() let existingEpisodeLookup = existingEpisodes.reduce([:], { (lookup, episode) -> [Int:Episode] in var mutableLookup = lookup mutableLookup[Int(episode.id)] = episode return mutableLookup }) Insert or Update Records in the Background container?.performBackgroundTask { moc in episodes.forEach { jsonEpisode in let model = existingEpisodeLookup[jsonEpisode.id] ?? Episode(context: moc) model.id = Int32(jsonEpisode.id) model.title = jsonEpisode.title model.summary = jsonEpisode.summary model.thumbnailURLValue = jsonEpisode.thumbnailURLValue } try! moc.save() } Merging Changes Automatically First, we set our view context to merge changes from the store, and pin changes to .current to always see the latest data. container.viewContext.automaticallyMergesChangesFromParent = true try! container.viewContext.setQueryGenerationFrom(.current) When the save happens on another context, it gets performed on the store, which will merge changes on the view context. Our fetched results controller detects this change and notifies its delegate: extension ViewController : NSFetchedResultsControllerDelegate { func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { loadFromCoreData() } }