How to Create Instances of Managed Object Subclasses in a Nsmanagedobject Swift Extension

How can I create instances of managed object subclasses in a NSManagedObject Swift extension?

(Updated for Swift 3/4 now. Solutions for earlier Swift versions
can be found in the edit history.)

You can use unsafeDowncast to cast the return value
of NSEntityDescription.insertNewObject() to Self
(which is the type on which the method is actually called):

extension NSManagedObject {
class func create(in context: NSManagedObjectContext) -> Self {
let classname = entityName()
let object = NSEntityDescription.insertNewObject(forEntityName: classname, into: context)
return unsafeDowncast(object, to: self)
}

// Returns the unqualified class name, i.e. the last component.
// Can be overridden in a subclass.
class func entityName() -> String {
return String(describing: self)
}
}

Then

let obj = YourEntity.createInContext(context)

works and the compiler infers the type of obj correctly as YourEntity.

Using Swift generics to create new NSManagedObjects

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"

NSManagedObject subclass' category equivalent in Swift?

A Swift extension is the right way to define additional methods for NSManagedObject subclasses.
You can put the extension into a separate file
(e.g. "BookExtensions.swift") so that they are not overwritten when
"Book.swift" is recreated in Xcode.

A generic static method to create NSManagedObject

It is not clear what your CRUD call is supposed to do since when you instantiate a NSManagedObject subclass it is automatically inserted into the context but a static method could looks like this, note that you need to send the NSManagedObjectContext since this is a static method

static func create<T: NSManagedObject>(in context: NSManagedObjectContext) -> T {
let object = T(context: context)
CRUD.insertToDatabase(object) //what happens here? Why send object?
return object
}

an alternative is to let the CRUD do this directly

func insertToDatabase<T: NSManagedObject>() -> T {
let object = T(context: self.mainContext)
//save?
return object
}

the first would then be called like this

let person = Person.create(in: someContext)

and the second

let person: Person = CRUD.insertToDatabase()

can not create subclasses of managed objects

If you set "Codegen" to "Class Definition", like in your example, Xcode does generate the NSManagedObject subclasses, but you do not actually see the in your project. Like stated in your posted quote, the files are generated in

~/Library/Developer/Xcode/DerivedData/...

You do not see them in your project, only the files in Derived Data, which you should not have to care about. Xcode does hold a reference though, so command+clicking in code jumps to the implementation as expected plus you are able to write extensions and such.

Find details in this answer.

Errors after 'Create NSManagedObject Subclass for CoreData Entities

The current default in Xcode is to automatically create subclasses of NSManagedObject for you in the /Users/<your user name>/Library/Developer/Xcode/DerivedData/AppName-agkwmibzbo‌​pevjgfajlcbyixzyev/B‌​uild/Intermediates/A‌​ppName.build/Debug-i‌​phonesimulator/AppNa‌​me.build/DerivedSour‌​ces/CoreDataGenerate‌​d/Modeldirectory; The DerivedData directory is where Xcode saves automatically generated code. You are redeclaring the same subclass by doing Editor>Create NSManagedObject Subclass... that is why you are getting the "Invalid redeclaration of 'UserRoutine' 'UserExercise' is ambiguous for type lookup in this context @NSManaged only allowed on an instance property or method" error. To resolve the errors and manually create a subclass of NSManagedObjects what you need to do is:

  1. Open terminal and navigate to /Users/<your user name>/Library/Developer/Xcode/DerivedData/AppName-agkwmibzbo‌​pevjgfajlcbyixzyev/B‌​uild/Intermediates/A‌​ppName.build/Debug-i‌​phonesimulator/AppNa‌​me.build/DerivedSour‌​ces/CoreDataGenerate‌​d/Model

  2. Run this command: rm -rf * (now be careful with this command, run it only when you get to the final directory where the generated codes are or you'll break your project for good)

  3. Delete your current data model

  4. Create a new data model

  5. Select your new data model's entity (do this for each entity within the data model) and go to its attributes inspector and set its Codegen to Manual/None Before the first run after you have created a new data model.

  6. Create a subclass of NSManagedObject by going to Editor>Create NSManagedObject Subclass...

Your errors should disappear.

Hope this helped!



Related Topics



Leave a reply



Submit