52

I'm new to Swift and I'm trying to learn how to use Core Data. But I'm getting this error and I'm not sure what I've done wrong. I've searched online and tried a few things but I can't get it right.

Failed to call designated initializer on NSManagedObject class 'FirstCoreData.Course'

When this line executes:

ncvc.currentCourse = newCourse

In this function:

class TableViewController: UITableViewController, AddCourseViewControllerDelegate {

var managedObjectContext = NSManagedObjectContext.init(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType)

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "addCourse" {
        let ncvc = segue.destinationViewController as! NewCourseViewController
        ncvc.delegate = self

        let newCourse = NSEntityDescription.insertNewObjectForEntityForName("Course", inManagedObjectContext: self.managedObjectContext) as! Course
        ncvc.currentCourse = newCourse

    }
}

Class generated by "Create NSManagedObject Subclass..." for Course entity:

import Foundation
import CoreData

class Course: NSManagedObject {

// Insert code here to add functionality to your managed object subclass

}

And:

import Foundation
import CoreData

extension Course {

    @NSManaged var title: String?
    @NSManaged var author: String?
    @NSManaged var releaseDate: NSDate?

}
Dan Beaulieu
  • 19,406
  • 19
  • 101
  • 135
Daniel
  • 1,399
  • 3
  • 16
  • 29

5 Answers5

102

The problem lies not in the code in your question, but in the snippet you included as comments to the other answer:

var currentCourse = Course()

This doesn't just declare currentCourse to be of type Course, it also creates an instance of the Course entity using the standard init method. This is expressly not allowed: You must use the designated initialiser: init(entity entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?). This is described in the Apple Documentation here.

I suspect you do not ever use the instance created by the above var definition, so just define it as being of type Course?:

var currentCourse : Course?

Since it is optional, you do not need to set an initial value, though you will need to unwrap the value whenever it is used.

pbasdf
  • 21,386
  • 4
  • 43
  • 75
25

The simplest way is this:

  • Define in the applicationDelegate a reference for the context
  • Instantiate the variable by passing the context

In the AppDelegate (outside the brackets):

let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext

And in the code:

let currentCourse = Course(context:context)

Now you have your entity created. But don't forget to save with:

appDelegate.saveContext()
Fab
  • 816
  • 8
  • 17
  • 1
    This line helped me fix my issue: let currentCourse = Course(context:context). I was returning it without any parameters, but after adding (context: myManagedObjectContext) it fixed my issue. – zeeshan Jan 03 '19 at 13:04
17

I had the same issue. And instantiating the object like this worked, for your course it would be something like this:

var currentCourse = Course.init(entity: NSEntityDescription.entityForName("Course", inManagedObjectContext:mox)!, insertIntoManagedObjectContext: mox)

instead of:

var currentCourse = Course()
julien
  • 437
  • 4
  • 9
2

I used this in Xcode 8.3.2 with Swift 3.1.

NSEntityDescription.insertNewObject(forEntityName: String(describing: type(of: Record())), into: managedObjectContext) as! Record

And got the same error message. But this data was inserted into db. So maybe this doesn't matter.

Lumialxk
  • 6,239
  • 6
  • 24
  • 47
0

Your currentCourse should be NSManagedObject class

Please refer this CoreData: error: Failed to call designated initializer on NSManagedObject class

Community
  • 1
  • 1
Vijay
  • 791
  • 1
  • 8
  • 23
  • If I declare currentCourse as NSManagedObject I will loose access to the title, author and releaseDate members. So then I don't know how to access the entities attributes. – Daniel Oct 23 '15 at 11:50
  • I think currentCourse is also the Course class so you will not loose the entities. – Vijay Oct 23 '15 at 12:00
  • Sorry I don't understand. At the moment I have var currentCourse = Course(). If I change that to var currentCourse = NSManagedObject() then everything which refers to the members of Course (e.g. currentCourse.title) say "title is not a member of NSManagedObject". – Daniel Oct 23 '15 at 12:05
  • Since Course in NSManagedObject class, you should initiate using this, `initWithEntity:insertIntoManagedObjectContext:` – Vijay Oct 23 '15 at 12:12
  • I've found lots of examples of this in Objective-C, but I'm struggling to find how to do it in Swift. The auto complete popup doesn't find anything for initWithEntity and I'm even struggling to find it in Swift in Apple's documentation. Are you able to show me how I use it in Swift please? – Daniel Oct 23 '15 at 13:01
  • Can you try like [this](http://stackoverflow.com/questions/24015185/generating-swift-models-from-core-data-entities) – Vijay Oct 23 '15 at 13:05
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/93176/discussion-between-vijay-and-daniel). – Vijay Oct 23 '15 at 13:27
  • Thanks, but I'm about to leave work. Unfortunately I'll have to continue with this tomorrow. – Daniel Oct 23 '15 at 14:06
  • @Daniel, check my answer tomorrow. If work then upvote it and accept my answer. – Vijay Oct 23 '15 at 14:14