I finally got around to trying out the new query generations in iOS 10 but when I turned it on, I started getting exceptions when calling mergeChanges(fromContextDidSave:). My app supports iOS 9 as well so I can't use NSPersistentContainer quit yet. Here's where I am setting up the Core Data stack: (also at https://gist.github.com/davbeck/85adfe8ab723562abf7c998e53f8e9f5)
/
static func defaultStoreURL() -> URL? {
do {
guard var url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier) else { return nil }
url.appendPathComponent("EngagementData")
try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true)
url.appendPathComponent("Data.sqlite3")
return url
} catch {
return nil
}
}
public let storeURL: URL?
public let managedObjectModel: NSManagedObjectModel = {
let momURL = Bundle(for: APIClient.self).url(forResource: "Realm", withExtension: "momd")!
return NSManagedObjectModel(contentsOf: momURL)!
}()
fileprivate(set) open lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let options = [
NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true,
]
if let storeURL = self.storeURL {
do {
self.logger.info("storeURL: \(self.storeURL)")
try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: self.storeURL, options: options)
return persistentStoreCoordinator
} catch let error {
self.logger.error("Could not create NSPersistentStoreCoordinator", error: error)
}
}
/
try! persistentStoreCoordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil)
return persistentStoreCoordinator
}()
fileprivate(set) public lazy var backgroundContext: NSManagedObjectContext = {
let context = ManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
context.persistentStoreCoordinator = self.persistentStoreCoordinator
context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
context.dispatchGroup = self.dispatchGroup
context.shouldDeleteInaccessibleFaults = true
if #available(iOS 10, *) {
do {
try context.setQueryGenerationFrom(.current)
} catch {
self.logger.error("could not activate query generation", error: error)
}
}
return context
}()
public func performBackgroundTask(_ block: @escaping (NSManagedObjectContext) -> Void) {
self.backgroundContext.perform {
block(self.backgroundContext)
}
}
fileprivate(set) public lazy var viewContext: NSManagedObjectContext = {
let context = ManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
context.persistentStoreCoordinator = self.persistentStoreCoordinator
context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
context.dispatchGroup = self.dispatchGroup
context.shouldDeleteInaccessibleFaults = true
if #available(iOS 10, *) {
do {
try context.setQueryGenerationFrom(.current)
} catch {
self.logger.error("could not activate query generation", error: error)
}
}
return context
}()
/
func viewContextDidSave(_ notification: Notification) {
self.logger.debug("viewContextDidSave: \(notification.userInfo)")
self.backgroundContext.perform {
self.backgroundContext.mergeChanges(fromContextDidSave: notification)
}
}
func backgroundContextDidSave(_ notification: Notification) {
self.logger.debug("backgroundContextDidSave: \(notification.userInfo)")
self.viewContext.perform {
self.viewContext.mergeChanges(fromContextDidSave: notification)
}
}
Inside of backgroundContextDidSave, self.viewContext.mergeChanges(fromContextDidSave: notification) causes an EXC_BAD_INSTRUCTION and prints out "More code needs to be written". Am I missing something? What other code needs to be written?!?!