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?!?!
Post
Replies
Boosts
Views
Activity
I'm experimenting with replacing my graph implementation with SwiftCharts. One issue I ran into is that I'm graphing stock data, but that data is only present during trading hours. In the screenshot I included, you can see my implementation on top vs the SwiftCharts version as well as the stocks app.
Because trading is from 9:30AM-4:00PM, if the times are graphed linearly, there will be large gaps for nights and weekends.
The way I implemented this before was to treat each "tick" of data as equal width. .chartXScale(type: .category) seems like it would do something similar, but if I try that I get the following error:
Fatal error: the specified scale type is incompatible with the data values and visual property.
How can you set a manual range on a chart? There is .chartXScale(range:) but the only options seem to be to add padding to the values in the chart. I need to have a specific start and end date.
In the contacts app there are contacts included that include "Siri found in Mail". I have an app that includes a directory of contact information. Is it possible to include contacts found in my app to the system?
The documentation states that you can use either finishDeferredLightweightMigrationTask or finishDeferredLightweightMigration to complete a deferred migration at a later time. However when I tried finishDeferredLightweightMigrationTask, I noticed that the metadata for the store isn't updated. How would you know when the migration has completed and you can stop calling finishDeferredLightweightMigrationTask?
The reason I was reaching for the individual migration task approach is that I thought it would be better for handling an expired background task since I could check for cancellation after each step.