Swift and CoreData Casting issues in test vs non-test

core-data, ios, swift

Solution

Your are totally right, the issue is the when you run the App it's looking for `myAppname.myEntity` and when you run as Test it's looking as `myAppnameTests.myEntity`. The solution I use at this time (Xcode 6.1) is to NOT fill the `Class` field in the CoreData UI, and to do it in code instead.

This code will detect if you are running as App vs Tests and use the right module name and update the `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
}()

Problem

I'm using Swift on Xcode 6 with `CoreData`. I've read the release notes and have seen this issue about making sure to mark up a core data model with a module name (app name) so you can cast an `NSManagedObject` to your model type at run time. When I do this, I can get an app to run properly (good!). However, my issue is, when I try to test that same code, the test will always crash whenever the cast happens with a `Swift dynamic cast failed` error (bad :(). This makes it difficult to test my application. Is there any impact on the module name we use when the app is built for test vs. running? Thanks in advance for any pointers... Follow up: This is not ideal: As noted above, In order for Swift to use a Core Data model, you need to decorate the class name with the name of your app. This works find for building the app, but the tests run under a different app name! That means you need to go into the data modeler and change that class name from `myAppname.myEntity` to `myAppnameTests.myEntity` before you can use those Entities by name when used by or called from a test.

Original source

Related problems