Testing Core Data - core-data

I want to set up a mock for my Core data manager.
I'm doing this the old way for the core data stack, but want to do it for the exercise.
In the main Core Data Manager I set up with
var objectContext: NSManagedObjectContext! = nil
var entity: NSEntityDescription! = nil
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
objectContext = appDelegate.persistentContainer.viewContext
entity = NSEntityDescription.entity(forEntityName: Constants.entityName, in: objectContext)!
Now obviously I can't use UIApplication's persistent container in my mock.
So I tried to use the following:
objectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
let entityOne = NSEntityDescription.insertNewObject(forEntityName: Constants.entityName, into: objectContext)
However I get the error "NSInvalidArgumentException", "+entityForName: nil is not a legal NSPersistentStoreCoordinator for searching for entity name 'TaskEntity'"
So how can I set a new objectContext for my mock?

One solution is to create a full Core Data stack but let the persistent store reside in memory only. This way you don't have to deal with some app delegate dependency. Set context to nil and remove the store from the coordinator afterwards in tearDown()
class TestExample: XCTestCase {
var storeCordinator: NSPersistentStoreCoordinator!
var managedObjectContext: NSManagedObjectContext!
var managedObjectModel: NSManagedObjectModel!
var store: NSPersistentStore!
override func setUp() {
super.setUp()
managedObjectModel = NSManagedObjectModel.mergedModel(from: nil)
storeCordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)
do {
store = try storeCordinator.addPersistentStore(
ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil)
} catch {
XCTFail("Failed to create a persistent store, \(error)")
}
managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = storeCordinator
}

Related

NSFetchedResultsController can't update the tableView swift4

I'm trying to make it work for last couple of days and can't get it working. Its something tiny detail obviously I can't seem to find.
Could you take a look and give me some insights about my code?
I'm trying to update the logView with app savings in the coredata.
Here's the entire code for ViewController and CoreData Handler.
/// fetch controller
lazy var fetchController: NSFetchedResultsController = { () -> NSFetchedResultsController<NSFetchRequestResult> in
let entity = NSEntityDescription.entity(forEntityName: "Logs", in: CoreDataHandler.sharedInstance.backgroundManagedObjectContext)
let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
fetchRequest.entity = entity
let nameDescriptor = NSSortDescriptor(key: "name", ascending: false)
fetchRequest.sortDescriptors = [nameDescriptor]
let fetchedController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: CoreDataHandler.sharedInstance.backgroundManagedObjectContext, sectionNameKeyPath: "duration", cacheName: nil)
fetchedController.delegate = self as? NSFetchedResultsControllerDelegate
return fetchedController
}()
override func viewDidLoad() {
title = "Week Log"
tableView.tableFooterView = UIView(frame: CGRect.zero)
tableView.separatorColor = UIColor.black
tableView.backgroundColor = UIColor.red
refreshView()
loadNormalState()
loadCoreDataEntities()
}
/**
Refresh the view, reload the tableView.
*/
func refreshView() {
loadCoreDataEntities()
tableView.reloadData()
}
/**
Load history entities from core data. (I'm printing on the console and
be able to see the the fetched data but I can't load it to tableView.)
*/
func loadCoreDataEntities() {
do {
try fetchController.performFetch()
} catch {
print("Error occurred while fetching")
}
}
import Foundation
import CoreData
class CoreDataHandler: NSObject {
/**
Creates a singleton object to be used across the whole app easier
- returns: CoreDataHandler
*/
class var sharedInstance: CoreDataHandler {
struct Static {
static var instance: CoreDataHandler = CoreDataHandler()
}
return Static.instance
}
lazy var backgroundManagedObjectContext: NSManagedObjectContext = {
let backgroundManagedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
let coordinator = self.persistentStoreCoordinator
backgroundManagedObjectContext.persistentStoreCoordinator = coordinator
return backgroundManagedObjectContext
}()
lazy var objectModel: NSManagedObjectModel = {
let modelPath = Bundle.main.url(forResource: "Model", withExtension: "momd")
let objectModel = NSManagedObjectModel(contentsOf: modelPath!)
return objectModel!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.objectModel)
// Get the paths to the SQLite file
let storeURL = self.applicationDocumentsDirectory().appendingPathComponent("Model.sqlite")
// Define the Core Data version migration options
let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
// Attempt to load the persistent store
var error: NSError?
var failureReason = "There was an error creating or loading the application's saved data."
do {
try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: options)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject
dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return persistentStoreCoordinator
}()
func applicationDocumentsDirectory() -> NSURL {
return FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).last! as NSURL
}
func saveContext() {
do {
try backgroundManagedObjectContext.save()
} catch {
print("Error while saving the object context")
// Error occured while deleting objects
}
}
You have a data source delegate somewhere. That data source delegate tells the table view how many items there are, and what their contents is. How does it know how many items? That must be stored somewhere.
When the fetch controller is successful, it must modify the data that the data source delegate relies on in some way, and then call reloadData. Are you doing this? Are you doing anything that causes the data source delegate to change the number of items it reports?
And calling loadCoreDataEntities, immediately followed by reloadData, is nonsense. loadCoreDataEntities is asynchronous. By the time you call reloadData, it hasn't loaded any entities yet. realodData is called when loadCoreDataEntities has finished.

Coredata returns duplicate values. Can anyone had the same issue?

Im using swift3. When fetching data from coredata, it returns duplicate values. Using software Datum, i understood that database only contains the original value.
class DatabaseManager: NSObject {
fileprivate static let sharedManager: DatabaseManager = DatabaseManager()
class var shared: DatabaseManager {
return sharedManager
}
/*Returns the ManagedObjectContext*/
var managedObjectContext: NSManagedObjectContext!
var privateManagedObjectContext: NSManagedObjectContext!
fileprivate var completionHandler: ((_ completed: Bool)-> Void)? = nil
override init() {
privateManagedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
if let appdelegate = UIApplication.shared.delegate as? AppDelegate {
managedObjectContext = appdelegate.managedObjectContext
privateManagedObjectContext.persistentStoreCoordinator = managedObjectContext.persistentStoreCoordinator
}
}
deinit {
managedObjectContext = nil
privateManagedObjectContext = nil
}
}
//Fetching data
func getItem()->[ListItem]{
var objects = [ListItem]()
var uniqueObjects:[ListItem] = [ListItem]()
let sort = NSSortDescriptor(key: "itemName", ascending: false)
let request : NSFetchRequest<ShoppyListItem> = ShoppyListItem.fetchRequest() as NSFetchRequest<ShoppyListItem>
//let predicate = NSPredicate(format:"excludedIDContain = %#","New")
// request.predicate = predicate
request.sortDescriptors = [sort]
do {
if objects.count > 0 {
objects.removeAll()
}
objects = try managedObjectContext?.fetch(request) ?? []
return objects
} catch {
print("Error with request: \(error)")
}
return objects
}
// objects = try managedObjectContext?.fetch(request) ?? [] returns duplicated objects
i got it. Im not mistaken about the count. It was due to concurrency. i was not running fetch on the safe thread of coredata. All i had to do was put the code inside perform block.
managedObjectContext.perform(block).
Got this from stanford ios tutorial named coredata demo. Video time 26:00. The professor explains this.

Setting up CDEPersistentStoreEnsemble gives [NSMapTable cde_strongToStrongObjectsMapTable]:

I am setting up ensembles to sync CoreData to iCloud.
But it crashes on launch:
[NSMapTable cde_strongToStrongObjectsMapTable]: unrecognized selector sent to class 0x10d978c70
2016-08-05 12:48:42.502 Shooters_Journal[30266:751831] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSMapTable cde_strongToStrongObjectsMapTable]: unrecognized selector sent to class 0x10d978c70'
I dont understand what this means. How do I proceed to debug??
I have added my CoreData Stack and Ensembles setup. For the record, the app works very well without setting up ensembles.
In my AppDelegate I have:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// setups
// Setup Ensemble
let modelURL = NSBundle.mainBundle().URLForResource("Myidentifier", withExtension: "momd")
cloudFileSystem = CDEICloudFileSystem(ubiquityContainerIdentifier: nil)
let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("CoreData.sqlite")
ensemble = CDEPersistentStoreEnsemble(ensembleIdentifier: "ShotsStore", persistentStoreURL: storeURL, managedObjectModelURL: modelURL!, cloudFileSystem: cloudFileSystem)
ensemble.delegate = self
return true
}
My CoreData stack is the default XCode creates
// MARK: - Core Data stack
lazy var applicationDocumentsDirectory: NSURL = {
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.count-1]
}()
lazy var managedObjectModel: NSManagedObjectModel = {
let modelURL = NSBundle.mainBundle().URLForResource("Myidentifier", withExtension: "momd")
return NSManagedObjectModel(contentsOfURL: modelURL!)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let storeUrl = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeUrl, options: nil)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return coordinator
}()
lazy var managedObjectContext: NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
The app compiles fine, but on start I get following error:
[NSMapTable cde_strongToStrongObjectsMapTable]: unrecognized selector
sent to class 0x10d978c70
All I now is that the line:
ensemble = CDEPersistentStoreEnsemble(ensembleIdentifier: "ShotsStore", persistentStoreURL: storeURL, managedObjectModelURL: modelURL!, cloudFileSystem: cloudFileSystem)
is causing the crash.
I have no idea if its the persistentStoreURL, managedObjectModelURL or cloudFileSystem that is cousing the error.
I think you forgot the -ObjC step in the README. That will cause all categories to be linked, which is causing the missing symbols error.

Swift SIGBART threat CoreData

I have the problem about SIGBART. i did google it and try to solve it.
but i only have it on one of my buttons.
This is how my tool bar said.
CoreData: error: -addPersistentStoreWithType:SQLite
configuration:(null)
URL:file:///var/mobile/Containers/Data/Application/D223A294-3617-494F-8774-9CA6DCB61C2D/Documents/SingleViewCoreData.sqlite
options:(null) ... returned error Error Domain=NSCocoaErrorDomain
Code=134100 "The managed object model version used to open the
persistent store is incompatible with the one that was used to create
the persistent store." UserInfo={metadata={
NSPersistenceFrameworkVersion = 637;
NSStoreModelVersionHashes = {
Item = ;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "7711BB5D-CAF4-4F2E-9122-AF54B74D3850";
"_NSAutoVacuumLevel" = 2; }, reason=The model used to open the store is incompatible with the one used to create the store} with
userInfo dictionary {
metadata = {
NSPersistenceFrameworkVersion = 637;
NSStoreModelVersionHashes = {
Item = ;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "7711BB5D-CAF4-4F2E-9122-AF54B74D3850";
"_NSAutoVacuumLevel" = 2;
};
reason = "The model used to open the store is incompatible with the one used to create the store"; } 2016-01-07 12:18:39.271
test7[2483:1077844] Unresolved error Error Domain=YOUR_ERROR_DOMAIN
Code=9999 "Failed to initialize the application's saved data"
UserInfo={NSLocalizedDescription=Failed to initialize the
application's saved data, NSLocalizedFailureReason=There was an error
creating or loading the application's saved data.,
NSUnderlyingError=0x134e63a80 {Error Domain=NSCocoaErrorDomain
Code=134100 "The managed object model version used to open the
persistent store is incompatible with the one that was used to create
the persistent store." UserInfo={metadata={
NSPersistenceFrameworkVersion = 637;
NSStoreModelVersionHashes = {
Item = ;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "7711BB5D-CAF4-4F2E-9122-AF54B74D3850";
"_NSAutoVacuumLevel" = 2; }, reason=The model used to open the store is incompatible with the one used to create the store}}},
[NSLocalizedDescription: Failed to initialize the application's saved
data, NSLocalizedFailureReason: There was an error creating or loading
the application's saved data., NSUnderlyingError: Error
Domain=NSCocoaErrorDomain Code=134100 "The managed object model
version used to open the persistent store is incompatible with the one
that was used to create the persistent store." UserInfo={metadata={
NSPersistenceFrameworkVersion = 637;
NSStoreModelVersionHashes = {
Item = ;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "7711BB5D-CAF4-4F2E-9122-AF54B74D3850";
"_NSAutoVacuumLevel" = 2; }, reason=The model used to open the store is incompatible with the one used to create the store}] (lldb)
Code on board:
import UIKit
import CoreData
class RecordTVC: UITableViewController, NSFetchedResultsControllerDelegate {
let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var frc : NSFetchedResultsController = NSFetchedResultsController()
func fetchRequest() ->NSFetchRequest {
let fetchRequest = NSFetchRequest(entityName: "users")
let sortDescriptior = NSSortDescriptor(key: "name", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptior]
return fetchRequest
}
func getFRC() ->NSFetchedResultsController {
frc = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
return frc
}
override func viewDidLoad() {
super.viewDidLoad()
frc = getFRC()
frc.delegate = self
do {
try frc.performFetch()
} catch {
print("failed to perform fetch")
return
}
self.tableView.rowHeight = 100
}
override func viewDidAppear(animated: Bool) {
frc = getFRC()
frc.delegate = self
do {
try frc.performFetch()
} catch {
print("failed to appear")
return
}
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
_ = frc.sections?.count
return 0
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
_ = frc.sections?[section].numberOfObjects
return 0
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
cell.textLabel?.textColor = UIColor.blueColor()
let users = frc.objectAtIndexPath(indexPath) as! Users
cell.textLabel?.text = users.name
let date = users.data
let note = users.note
cell.detailTextLabel!.text = " Date: \(date!) Note: \(note!)"
return cell
}
}
And on the appDelegate:
import UIKit
import CoreData
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
self.saveContext()
}
// MARK: - Core Data stack
lazy var applicationDocumentsDirectory: NSURL = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "mis-dentmate.com.tw.test7" in the application's documents Application Support directory.
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.count-1]
}()
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = NSBundle.mainBundle().URLForResource("test7", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return coordinator
}()
lazy var managedObjectContext: NSManagedObjectContext = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
// MARK: - Core Data Saving support
func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
abort()
}
}
}

Can't Unwrap Optional.None when using CoreData in Swift

Ok so the problem actually occurs once the code bit var context: NSManagedObjectContext = appDel.managedObjectContext is run I commented it out to confirm that it was that line and it was please note this is my first time learning iOS programming so please try to be as specific as possible in your answer thank you :)
import UIKit
import CoreData
class SecondViewController: UIViewController, UITextFieldDelegate {
#IBOutlet var txtName : UITextField
#IBOutlet var txtDesc : UITextField
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
self.view.endEditing(true)
}
#IBAction func hitAdd(sender : UIButton) {
glTask.newTask(txtName.text, desc: txtDesc.text)
txtName.text = ""
txtDesc.text = ""
self.view.endEditing(true)
self.tabBarController.selectedIndex = 0
var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
Right here V
var context: NSManagedObjectContext = appDel.managedObjectContext
This crashes the app once button is pressed ^
The code error message is fatal error Cant unwrap Optional.None
var newTask = NSEntityDescription.insertNewObjectForEntityForName("Tasks", inManagedObjectContext: context) as NSManagedObject
newTask.setValue("test task", forKey: "myTask")
newTask.setValue("test Description", forKey: "myDesc")
context.save(nil)
//println(newTask)
println("Task was saved.")
}
// UITextField Delegate
func textFieldShouldReturn(textField: UITextField!) -> Bool {
textField.resignFirstResponder()
return true
}
}
Looking at the Core Data stack in Swift, managedObjectContext is implemented like this:
var managedObjectContext: NSManagedObjectContext {
if !_managedObjectContext {
let coordinator = self.persistentStoreCoordinator
if coordinator != nil {
_managedObjectContext = NSManagedObjectContext()
_managedObjectContext!.persistentStoreCoordinator = coordinator
}
}
return _managedObjectContext!
}
var _managedObjectContext: NSManagedObjectContext? = nil
As you can see it is backed by an Optional.
The place where this can go wrong is here:
_managedObjectContext = NSManagedObjectContext()
_managedObjectContext!.persistentStoreCoordinator = coordinator
if NSManagedObjectContext() returns a nil, then the backing _managedObjectContext will be nil and you will get this crash at the line where you unwrap it return _managedObjectContext!
To debug this, dig deeper down the stack, its most likely failing to initialize the object model or persistant store, and thus returning nil to you.
Edit:
In the definiton of the getter for var persistentStoreCoordinator: NSPersistentStoreCoordinator
They provide a location (the wall of comments) where you should debug this exact type of issue.
Not sure if OP ever figured this out, but I had a similar issue and realized that the code I copied from another app's AppDelegate was using the project name of that app and that I had forgot to change this line: let modelURL = NSBundle.mainBundle().URLForResource("CoreData", withExtension: "momd") to use "CoreData" instead of the "test" it had from another project.

Resources