Unable to find specific subclass of NSManagedObjec

2019-01-01 05:40发布

问题:

I\'m working on developing an app with Core Data. When I created an instance using:

let entity = NSEntityDescription.entityForName(\"User\", inManagedObjectContext: appDelegate.managedObjectContext)
let user = User(entity: entity, insertIntoManagedObjectContext: appDelegate.managedObjectContext)

I got a warning in log:

CoreData: warning: Unable to load class named \'User\' for entity \'User\'.  Class not found, using default NSManagedObject instead.

How could I fix it?

And another question, how can I define an instance method in NSManagedObject subclass?

Edit:

I have specified class of the entity as in the following screenshot:

\"enter

回答1:

Update for Xcode 7 (final): Prepending the module name to the class (as in Xcode 6 and early beta releases of Xcode 7) is no longer necessary. The Apple documentation Implementing Core Data Managed Object Subclasses has been updated accordingly.

The Data Model inspector has now two fields \"Class\" and \"Module\" for an entity:

\"enter

When you create a Swift managed object subclass for the entity, the \"Module\" field is set to \"Current Product Module\", and with this setting creating instances works both in the main application and in unit tests. The managed object subclass must not be marked with @objc(classname) (this was observed in https://stackoverflow.com/a/31288029/1187415).

Alternatively, you can empty the \"Module\" field (it will show \"None\") and mark the managed object subclasses with @objc(classname) (this was observed in https://stackoverflow.com/a/31287260/1187415).


Remark: This answer was originally written for Xcode 6. There were some changes in the various Xcode 7 beta releases with respect to this problem. Since it is an accepted answer with many upvotes and links to it, I have tried to summarize the situation for the current Xcode 7 final version.

I did both my own \"research\" and read all the answers to both this question and the similar question CoreData: warning: Unable to load class named. So attribution goes to all of them, even if I don\'t list them specifically!


Previous answer for Xcode 6:

As documented in Implementing Core Data Managed Object Subclasses, you have to prefix the entities class name in the Class field in the model entity inspector with the name of your module, for example \"MyFirstSwiftApp.User\".



回答2:

Just as a side-note. i had the same issue. And all i had to do was add @objc(ClassName) in my class file.

Example:

@objc(Person)
class Person { }

And that solved my issue.



回答3:

The accepted answer to this question helped me resolve the same issue but I had a caveat that I thought would be helpful to others. If your project (module) name has a space in it you must replace the space with an underscore. For example:

Entity: MyEntity Class: My_App_Name.MyClass



回答4:

Remember to remove your module:

\"enter



回答5:

Depending if you are running as App vs Tests the issue can be that the app is looking for <appName>.<entityName> and when it\'s running as test it\'s looking as <appName>Tests.<entityName>. 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
}()


回答6:

If you are using a hyphen in your project name like \"My-App\" then use an underscore instead of the hyphen like \"My_App.MyManagedObject\". In general, look at the name of the xcdatamodeld file and use the same prefix as in that name. I.e. \"My_App_1.xcdatamodeld\" requires the prefix \"My_App_1\"



回答7:

This may help those experiencing the same problem. I was, with Swift 2 and Xcode 7 beta 2.

The solution in my case was to comment out @objc(EntityName) in EntityName.swift.



回答8:

I had the same warning, though my app appeared to run fine. The problem was that when running Editor > Create NSManagedObject Subclass on the last screen I used the default Group location, with no Targets displayed or checked, which saved the subclass in the top MyApp directory where MyApp.xcodeproj was located.
The warning went away when I instead changed the Group to be in the MyApp subfolder and checked the MyApp target.



回答9:

By the way be carful what you add as a prefix: My App is called \"ABC-def\" and Xcode has converted the \"-\" into a \"_\".

To be safe look into the finder, find your project files and see what it says for your data model (for example \"ABC_def.xcdatamodeld\") and use what is written there EXACTLY!!!



回答10:

The above answers were helpful. This quick sanity check may save you some time. Go into Project > Build Phases > Compile Sources and remove your xcdatamodeld and your model files with the \"-\" button, and then add them right back with the \"+\" button. Rebuild -- that may take care of it.



回答11:

The above answers helped me to solve different issue connected with Objective-C (maybe it will help someone):

If you refactored entity names, don\'t forget to change \"Class\" in \"Utilities Panel\" as well.



回答12:

The above answers helped me but this may help somebody. If like me you did them and are still having a problem, remember to simply \'clean your project\'. For XCode8, Product > Clean. Then run again.



回答13:

In Xcode 7 Entity and Class names can be the same but Codegen should be Class Definition. In that case there will be no warning etc.enter image description here