2

So, I want to write a generic function on a NSManagedObject extension to create a new object.

public extension NSManagedObject {
    class var entityName: String {
        var name = NSStringFromClass(self)
        name = name.components(separatedBy: ".").last!
        return name
    }

    class func create<T>() -> T {
        guard let entityDescription = NSEntityDescription.entity(forEntityName: T.entityName, in: CoreDataManager.tripregi.managedObjectContext) else { fatalError("Unable to create \(T.entityName) NSEntityDescription") }
        guard let object = NSManagedObject(entity: entityDescription, insertInto: CoreDataManager.tripregi.managedObjectContext) as? T else { fatalError("Unable to create \(T.entityName) NSManagedObject")}
        return object
    }
}

When I try to use this as follows:

let employee = User.create() //FYI:User is a core data entity
employee.name = "The Dude"

I get the following error in the extension

Type 'T' has no member 'entityName'

And the following error on the User.create() part:

Generic parameter 'T' could not be inferred

I can fix that by specifying T:NSManagedObject in the extension, but then the class is no longer a User class and no longer has the attribute name....

What am I missing to have a 'NSManagedObject' of type 'User' created by 'User.create()' ?

Tycho Pandelaar
  • 7,367
  • 8
  • 44
  • 70

1 Answers1

4

Make T be of type NSManagedObject and also tell the compiler that employee is a User

class func create<T: NSManagedObject>() -> T {
   ...
}

let employee: User = User.create()
employee.name = "The Dude"
Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52