How to add Core Data to existing Xcode 9 Swift 4 iOS 11 project?

If you're lazy like me, here's all the code you need to copy from the new Core Data project... (why make everyone create a new project?). Change YOUR_APP_NAME_HERE

At the top of your AppDelegate.swift file:

import CoreData

At the bottom of AppDelegate.swift file, before the ending curly bracket:

// MARK: - Core Data stack

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()
    }

lazy var persistentContainer: NSPersistentContainer = {
    /*
     The persistent container for the application. This implementation
     creates and returns a container, having loaded 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.
    */
    let container = NSPersistentContainer(name: "YOUR_APP_NAME_HERE")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() 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.

            /*
             Typical reasons for an error here include:
             * The parent directory does not exist, cannot be created, or disallows writing.
             * The persistent store is not accessible, due to permissions or data protection when the device is locked.
             * The device is out of space.
             * The store could not be migrated to the current model version.
             Check the error message to determine what the actual problem was.
             */
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()

// MARK: - Core Data Saving support

func saveContext () {
    let context = persistentContainer.viewContext
    if context.hasChanges {
        do {
            try context.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() 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
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

go to File > new file... select core Data under iOS and select Data Model you'll still need some code which xcode auto generates whenever you select core data during project creation. to get it, just create new project with core data option checked and copy all the code written under ** //Mark: - Core Data Stack** comment in AppDelegate.swift and add

import CoreData

above

OPTIONAL

And don't forget to change the name of the app after copying the completion block for lazy var persistentContainer. Change the name of your app on this part *NSPersistentContainer(name: "SHOULD-BE-THE-NAME-OF-YOUR-APP") And managedObjectModel function of the code you just copied**


I know this is answered, but I believe the actual problem is with Apple's Documentation. If you compare the Objective-C code to the Swift code, you will see that var managedObjectContext: NSManagedObjectContext is not actually defined. You should replace that line with var persistentContainer: NSPersistentContainer. This is the Objective-c interface

@interface MyDataController : NSObject
@property (strong, nonatomic, readonly) NSPersistentContainer *persistentContainer; 
- (id)initWithCompletionBlock:(CallbackBlock)callback;
@end

So DataController.swift should be:

class DataController: NSObject {
 // Delete this line   var managedObjectContext: NSManagedObjectContext
    var persistentContainer: NSPersistentContainer
    init(completionClosure: @escaping () -> ()) {
        persistentContainer = NSPersistentContainer(name: "DataModel")
        persistentContainer.loadPersistentStores() { (description, error) in
          if let error = error {
              fatalError("Failed to load Core Data stack: \(error)")
          }
          completionClosure()
       }
    }
}

As for the rest of your code, it's not necessary Apple Docs.

Prior to iOS 10 and macOS 10.12, the creation of the Core Data stack was more involved

That section of code is showing you the old way.