How to make a designated initializer for NSManagedObject subclass in Swift?

bogen picture bogen · Oct 17, 2014 · Viewed 20.6k times · Source
class Alternative: NSManagedObject {

    @NSManaged var text: String
    @NSManaged var isCorrect: Bool
    @NSManaged var image: NSData
} 

convenience init(text: String, isCorrect: Bool, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
        let alternative = Alternative(entity: entity, insertIntoManagedObjectContext: context) as Alternative
        alternative.text = text
        alternative.isCorrect = isCorrect
        return alternative
}

I want to make a method that lets me initialize new objects with this call:

let newAlternative = Alternative("third platform", True, entityDescription, managedObjectContext)

But i get the error:

Convenience initializer for Alternative must delegate with self.init

What do i need to change in my initalizer to make my example usage work?

Answer

Martin R picture Martin R · Oct 17, 2014

A convenience initializer must call the designated initializer on self:

convenience init(text: String, isCorrect: Bool, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    self.init(entity: entity, insertIntoManagedObjectContext: context)
    self.text = text
    self.isCorrect = isCorrect
}

which would be called as

let newAlternative = Alternative(text: "third platform", isCorrect: true,
     entity: entityDescription, insertIntoManagedObjectContext: managedObjectContext)

In addition, you could also move the creation of the entity description into the convenience initializer instead of passing it as an argument (as motivated by Mundi's answer):

convenience init(text: String, isCorrect: Bool, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    let entity = NSEntityDescription.entityForName("Alternative", inManagedObjectContext: context)!
    self.init(entity: entity, insertIntoManagedObjectContext: context)
    self.text = text
    self.isCorrect = isCorrect
}