Gerd Castan
Gerd Castan

Reputation: 6849

Core Data NSManagedObject downcast with XCode 7 and Swift

Running the following code aborts in the return line

Type is not Workout 
Could not cast value of type 
'NSManagedObject_Workout_' (0x7fcca20620f0) to 
'AppName.Workout' (0x100ea5f40)). 

The part inside if let... is never executed.

func createWorkoutWithName (name: String) -> Workout? {
    let entityName = NSStringFromClass(Workout.classForCoder())
    let newEntity = NSEntityDescription.insertNewObjectForEntityForName(entityName, inManagedObjectContext: managedObjectContext)
    if let newEntity = newEntity as? Workout {
        newEntity.name = name
    }
    NSLog("createWorkoutWithName: Type is not Workout")
    return (newEntity as! Workout)

}

I had this problem in the past and I solved it in XCode 6.x by going in the entity inspector and setting Class = AppName.Workout

One of several answers that suggests this solution is How come I can cast to NSManagedObject but not to my entity's type?

XCode 7 adds a new twist to this problem: When I set

Class = AppName.Workout

in the entity inspector, XCode 7 changes the class name automagically to

Class = AppNameWorkout

by removing the dot between AppName and ClassName.

So how can I do this in XCode 7 when I can't set a dot between AppName and ClassName?

Upvotes: 0

Views: 1284

Answers (3)

Bourne
Bourne

Reputation: 2596

The combination of these solutions and the link you provided got me to the solution, but it took me a while to piece it all together. This is what I came up with (and it was basically just an oversight):

  1. Click on .xcdatamodelId file in your file structure/project navigator pane (far left).
  2. Select the entity that you are having issues with.
  3. In the Utilities pane (far right), look for the icon that looks like a 1997 cell phone, the Data Model Inspector.
  4. Under the entity settings, you should see two fields, "Name" and "Class" - set up "Class" with the name of the class you are using (typically the same as "Name").

Thats where I messed up, even though all my other entities had this set, I had forgotten to set this on this particular entity. You'll even notice before you follow these steps that the default "class" is NSObject, reflecting the error message. Some of the other solutions here likely ultimately do the same thing, but I found this the simplest/quickest solution.

I should note that I already had some of the other items noted set, like the @objc(Entity) interoperability reference.

Upvotes: 0

You need two fixes: First: Set your entity class name as your entity name. For example:

Entity name = Entity
Class name = Entity

Second: add this code above your entity class file:

@obj(Entity name)

For example:

@obj(Entity)
Class Entity: NSManagedObject { 
                   ...
}

Upvotes: 0

Pankaj Dekate
Pankaj Dekate

Reputation: 74

Go to your cdatamodel..where you declared your entity..There is a Default Configuration below the Entity. Check the Class column against your entity. By default this will have a dot prefixed. Remove the dot prefix .And it should work. And from what i see is you do not have to prefix your entity class name with the module name in Xcode 7. Hence you cannot use a dot in the class name.I am a newbie in iOS development. So i might not be totally right. But removing the dot prefix solved my issue in Xcode 7.

Upvotes: 5

Related Questions