Reputation: 2490
I have a class that inherits from NSManagedObject
. I'm using this object for model data and it's also being persisted.
class Foo: NSManagedObject {
@NSManaged var firstVar: String
@NSManaged var secondVar: String
let entity = NSEntityDescription.entityForName("Foo", inManagedObjectContext: managedObjectContext)
let createdManagedObject = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedObjectContext) as? Foo
}
I can create the object and get the NSManagedObject
instance, but I can't downcast it to actual class.
Actually, if I downcast it form optional value, then I will get nil value and if I downcast with unwrapping then it will crash.
When downcast with nil value debugger inspector shows type: Module.Foo, which I believe is the root of the problem.
Of course I tried with naming the class in .xcmodel inspector, tried to name Entity as Module.Foo, but the latter is not allowed as of Xcode 7 any more anyway.
All together: no success. Now I have to access Foo
object through KV, which is kind of awkward.
Anyone solved this issue yet?
EDIT: Adding the code to show creation and down-casting. I had issues with Xcode 7.0 and now same with 7.1.1
Upvotes: 1
Views: 1186
Reputation: 2490
It seems that the main problem was the target. Thanks to Martin R for pointing me to the problem.
Problem was, that also the code in the main app was part or another target, similar to tests. When object was retrieved from Core Data, it's class signature was Target.Foo and if you tried to cast it to Foo
in Target2, you got the error message that cast from Target.Foo
to Target2.Foo
is not possible and unfortunately this message didn't show in a log unless the log was empty ??
It doesn't matter at all, how you name the Class or Module if at all in setting below:
The only thing that matters is that your .xcmodel is in the same target than the code that accesses it.
Upvotes: 1
Reputation: 1091
You need to instantiate the Foo-Class directly:
let createdManagedObject = Foo(entity: entity!, insertIntoManagedObjectContext: managedObjectContext)
If you still want to encapsule the code to manage CoreData, you could do something similar to the following:
static func newInstanceForEntityName(name: String, context: NSManagedObjectContext) -> NSManagedObject {
let anyType: AnyObject.Type = NSClassFromString(name)!
let nsmType: NSManagedObject.Type = anyType as! NSManagedObject.Type
let entity = NSEntityDescription.entityForName(name, inManagedObjectContext: context)
return nsmType.init(entity: entity!, insertIntoManagedObjectContext: context)
}
You can use it like:
let foo = newInstanceForEntityName("Foo", context: context) as! Foo
Upvotes: 0
Reputation: 1091
You need to add the objc
annotation to your class:
@objc(Foo)
class Foo: NSManagedObject {
...
}
Upvotes: 0
Reputation: 100701
You need to edit the data model configuration to tell CoreData which class to use for a specific entity. The actual entity name itself has no impact on the instantiated class.
Upvotes: 0