0

Having problem getting this to work, inside User.provideInstance I'm unable to initialize Self and return. Any thoughts?

extension NSManagedObject {
    public convenience init(managedObjectContext: NSManagedObjectContext) {
        let entity = NSEntityDescription.entityForName(String(self.dynamicType), inManagedObjectContext: managedObjectContext)!
        self.init(entity: entity, insertIntoManagedObjectContext: managedObjectContext)
    }
}

public protocol Deserializable {
    static func provideInstance(json: [NSObject: AnyObject]) -> Self
}

@objc(User) public class User: NSManagedObject, Deserializable {

    public static func provideInstance(json: [NSObject: AnyObject]) -> Self {
       let context = DIContainer.instance.resolve(CoreDataStack.self).managedObjectContext
       let instance = self.init(managedObjectContext: context)
       return instance
    }
}

Error is on let instance = self.init(managedObjectContext: context):

Constructing an object of class type Self with a metatype value must use a required initializer

2
  • What error do you get? Commented Jun 11, 2016 at 21:00
  • @jtbandes updated question and included error Commented Jun 11, 2016 at 21:03

2 Answers 2

1

Why bother with initializers?

extension NSManagedObject {
    class func provide(managedObjectContext managedObjectContext: NSManagedObjectContext) -> Self {
        let entity = NSEntityDescription.entityForName(String(self.dynamicType), inManagedObjectContext: managedObjectContext)!
        return self.init(entity: entity, insertIntoManagedObjectContext: managedObjectContext)
    }
}

public protocol Deserializable {
    static func provideInstance(json: [NSObject: AnyObject]) -> Self
}

@objc(User) public class User: NSManagedObject, Deserializable {

    public static func provideInstance(json: [NSObject: AnyObject]) -> Self {
        let context = ...
        let instance = self.provide(managedObjectContext: context)
        return instance
    }
}

The problem with initializers is that they are not always inherited, unless they are required. And you cannot create a required initializer in an extension.

Sign up to request clarification or add additional context in comments.

2 Comments

How is this any different from what I posted?
I have no forced casts there.
1

As the error said, you need a required initializer to create an object, incase you subclass. Add final before your class to prevent this error.

Try this if you need to subclass:

@objc(User) public class User: NSManagedObject, Deserializable {

private static func pInstance<T>(json: [NSObject: AnyObject]) -> T {
    let context = DIContainer.instance.resolve(CoreDataStack.self).managedObjectContext
    let copy: NSManagedObject = NSManagedObject(managedObjectContext: context)
    let instance = copy as! T
    return instance
}

public static func provideInstance(json: [NSObject: AnyObject]) -> Self {
        return pInstance(json)
    }
}

Basically, create a helper function to create an instance of T based on the base class, NSManagedObject. Then use it the actual provideInstance function with the inferred type Self.

1 Comment

If I add final it means I won't be able to create a subclass of User anymore

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.