fredap
(Fred Appelman)
1
Hi,
I have a problem with a combination of CoreData and Class naming.
I am generating the CoreData model dynamically by code. I. Have the following code fragment (highly simplified) that works:
class Test: NSManagedObject {
@NSManaged var attribute: Date
}
class AttributeTests: XCTestCase {
func testDefaultValueDate3() throws {
let model = try CoreDataModel(databaseName) {
Entity(Const.entityName, managedObjectClass: Test.self) {
Attribute("attribute", type: Date.self)
.defaultValue(Const.defaultDateValue3)
}
}
let container = model.createInMemoryContainer()
let testRecord(context: container.viewContext)
}
}
The above code works as expected. Inside the model I am using String(reflecting:) to get the fully qualified name of the Test class. So far so good.
The problem arises if I move the Test class inside the test framework.
class AttributeTests: XCTestCase {
func testDefaultValueDate3() throws {
class Test: NSManagedObject {
@NSManaged var attribute: Date
}
let model = try CoreDataModel(databaseName) {
Entity(Const.entityName, managedObjectClass: Test.self) {
Attribute("attribute", type: Date.self)
.defaultValue(Const.defaultDateValue3)
}
}
let container = model.createInMemoryContainer()
let testRecord(context: container.viewContext)
}
}
This now fails with an error message like:
An NSManagedObject of class '_TtCFC18CoreDataModelTests14AttributeTests21testDefaultValueDate3FzT_T_L_4Test' must have a valid NSEntityDescription. (NSInvalidArgumentException)
The problem is coming from the fact that I cannot figure out what the fully qualified name of the Test class is. If I check the output of the statement print(String(reflecting: Test.self)) I get the output:
CoreDataModelTests.AttributeTests.(unknown context at $1014d58f4).(unknown context at $1014d5900).Test
Does someone know how to get the fully qualified name of the Test class? Can I somehow address the "unknown context" message.
Dlemex
(David Edwards)
2
Add an @objc(Test) to the class. It doesn't matter that you are not using Objective-C. There are requirements in CoreData. Finally, it is best to keep the model in a static (especially when testing) as multiple model instances will confuse everything.
1 Like
fredap
(Fred Appelman)
3
Thank you for your reply. Just for clarity I changed it into:
class AttributeTests: XCTestCase {
func testDefaultValueDate3() throws {
@objc class Test: NSManagedObject {
@NSManaged var attribute: Date
}
....
}
Unfortunately this does not solve the issue. The behavior is identical.
fredap
(Fred Appelman)
4
To follow-up on myself. It turns out that you can set the class name using the following syntax:
class AttributeTests: XCTestCase {
func testDefaultValueDate3() throws {
@objc(Test) class Test: NSManagedObject {
@NSManaged var attribute: Date
}
....
}
I can work with this. Thanks for the support.
1 Like
Dlemex
(David Edwards)
5
Yeah, adding the class name is required to the objc declaration is required. Sorry, I should have been clearer. Good luck.