I am rewriting my previous objC app in Swift 2.2. This is cocoa application where I am using NSArrayController
to fill NSTableView
contents.
The error is obvious, although similar setup worked in Objective C app.
Here is my AppDelegate:
var coreStack:AP_CoreDataStack!
var mainContext:NSManagedObjectContext!
override func awakeFromNib() {
coreStack = AP_CoreDataStack(){ (result) -> () in
if result {
self.mainContext = self.coreStack.mainContext
}
}
}
Setup of Core Data Stack
// MARK: - AP_CoreDataStack Class
class AP_CoreDataStack {
let mainContext: NSManagedObjectContext
let mastercontext: NSManagedObjectContext
var workerContext: NSManagedObjectContext?
internal typealias CallBack = (result:Bool) -> Void
init ( callback: CallBack) {
let modelURL = NSBundle.mainBundle().URLForResource("appNameSWIFT", withExtension: "momd")
if (modelURL == nil) {
print("Failed to initialize modelURL: \(modelURL)")
}
let mom = NSManagedObjectModel(contentsOfURL: modelURL!)
if mom == nil {
print("Failed to initialize model")
}
let psc = NSPersistentStoreCoordinator(managedObjectModel: mom!)
mastercontext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
mastercontext.persistentStoreCoordinator = psc
mainContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
mainContext.parentContext = mastercontext
// add store to psc in background thread
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
//BACKGROUND THREAD
// adding store to persistent store coordinator
let options = [NSInferMappingModelAutomaticallyOption:true,
NSMigratePersistentStoresAutomaticallyOption:true]
do {
// store = try psc.addP
try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: applicationDocumentDirectory(), options: options)
} catch let error as NSError {
print("Error: Failed to load store \(error.localizedDescription), \(error.userInfo)")
}
// MAIN THREAD
dispatch_async(dispatch_get_main_queue(), { () -> Void in
// On Main thread pass message that stack setup is complete
callback(result: true)
})
})
}
Above is the Swift version of my Obj C code which worked fine. I have an NSArrayController
in xib file which is bound to Entity
and NSManagedObjectContext
in IB:
// Bind To Delegate
self.mainContext
It seems Array controller is accessing mainContext before it is initialised, but this is the same setup which worked in objC, so why it is causing error in Swift.
EDIT: I am using regular xib file.
EDIT 2:
Evidently mainContext is not nil as calling it here works correctly
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
let request = NSFetchRequest(entityName: "AP_EntityA")
let list:Array<AnyObject>
do {
list = try coreStack.mainContext.executeFetchRequest(request)
for item in list {
let product = item as! AP_EntityA
print("item name is: \(product.uniqueName)")
}
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
}
Add the dynamic
keyword to make Swift properties KVO compliant.
dynamic var mainContext:NSManagedObjectContext!