Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 334
bogen Avatar asked Oct 17 '14 15:10

bogen


People also ask

How do I create a subclass in NSManagedObject?

From the Xcode menu bar, choose Editor > Create NSManagedObject Subclass. Select your data model, then the appropriate entity, and choose where to save the files. Xcode places both class and properties files into your project.

What is designated initializer in Swift?

Designated initializers are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up the superclass chain.

How many types of Initializers are there in Swift?

Swift defines two kinds of initializers for class types to help ensure all stored properties receive an initial value. Designated initializers are the primary initializers for a class.

What is NSEntityDescription in Swift?

Retrieving a description by its name class func entity(forEntityName: String, in: NSManagedObjectContext) -> NSEntityDescription? Returns the entity with the specified name from the managed object model associated with the specified managed object context's persistent store coordinator.


2 Answers

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 } 
like image 67
Martin R Avatar answered Sep 21 '22 13:09

Martin R


I simply did this with a class function:

class func newInstance(text: String, notes:String,                      context: NSManagedObjectContext) -> Item {     var item = NSEntityDescription.insertNewObjectForEntityForName("Item",                 inManagedObjectContext: context) as Item     item.notes = notes     item.text = text     return item } 

which you can call like this (almost as pretty):

let item = Item.newInstance(text, notes:notes, context:context) 
like image 34
Mundi Avatar answered Sep 21 '22 13:09

Mundi