Fast and CoreData casting questions in tests against non-test

I am using Swift on Xcode 6 with CoreData .

I read the release notes and saw this problem about marking the main data model with the module name (application name) so that you can cast the NSManagedObject type to the model type at runtime.

When I do this, I can get the application to work correctly (good!). However, my problem is that when I try to execute the test with the same code, the test will always fail every time a Swift dynamic cast failed (bad :() error occurs. This makes testing my application difficult.

Is there any effect on the name of the module that we use when the application is created for testing or is running?

Thanks in advance for any pointers ...

Following actions:

This is not ideal: As stated above, for Swift to use the Core Data model, you need to decorate the class name with the name of your application. This works to create the application, but tests run under a different application name! This means that you need to enter the data data model and change this class name from myAppname.myEntity to myAppnameTests.myEntity before you can use these objects by name when using or calling from a test.

+5
ios swift core-data
source share
2 answers

You are absolutely right, the problem is when you run the application that is looking for myAppname.myEntity , and when you run it as Test, it looks like myAppnameTests.myEntity . The solution I'm using at this time (Xcode 6.1) should NOT populate the Class field in the CoreData user interface and do this instead of code.

This code will detect that you are running as an application against tests, and use the correct module name and update managedObjectClassName .

 lazy var managedObjectModel: NSManagedObjectModel = { // The managed object model for the application. This property is not optional... let modelURL = NSBundle.mainBundle().URLForResource("Streak", withExtension: "momd")! let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)! // Check if we are running as test or not let environment = NSProcessInfo.processInfo().environment as [String : AnyObject] let isTest = (environment["XCInjectBundle"] as? String)?.pathExtension == "xctest" // Create the module name let moduleName = (isTest) ? "StreakTests" : "Streak" // Create a new managed object model with updated entity class names var newEntities = [] as [NSEntityDescription] for (_, entity) in enumerate(managedObjectModel.entities) { let newEntity = entity.copy() as NSEntityDescription newEntity.managedObjectClassName = "\(moduleName).\(entity.name)" newEntities.append(newEntity) } let newManagedObjectModel = NSManagedObjectModel() newManagedObjectModel.entities = newEntities return newManagedObjectModel }() 
+4
source share

You need to add one line to the Entity.swift file to make it also an Objective-C class as follows:

 @objc(YourEntity) class YourEntity: NSManagedObject { ... } 

I think this is a mistake if your project does not contain any Objective-C code. However, you need to add this line until it is fixed.

I found out from here.

Youtube video at 11:45

+1
source share

All Articles