CoreData: warning: Unable to load class named

JimmyJammed picture JimmyJammed · Oct 28, 2014 · Viewed 36.3k times · Source

I am duplicating an existing Objective-C TV Show app to a new Swift version using Xcode 6.1 and am having some issues with CoreData.

I have created a model of 4 entities, created their NSManagedObject subclass (in Swift), and all files have the proper app targets set (for 'Compile Sources').

I am still getting this error whenever I try to insert a new entity:

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

A few comments:

When saving to Core Data, I use the parent-child context way to allow background threading. I do this by setting up the ManagedObjectContext using:

lazy var managedObjectContext: NSManagedObjectContext? = {
  // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
  let coordinator = self.persistentStoreCoordinator
  if coordinator == nil {
    return nil
  }
  var managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType)
  managedObjectContext.persistentStoreCoordinator = coordinator
  return managedObjectContext
}()

and by saving data using:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
  var context = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
  context.parentContext = self.managedObjectContext!
  ...rest of core data saving code here...
})

Answer

Mundi picture Mundi · Oct 28, 2014

This warning is one of the quirks we have to deal with while the details of the Swift implementation are being ironed out. The warning occurs spuriously, i.e. your setup might work even if you do not follow the steps outlined below.

I have been able to get rid of it in most cases by making sure that the class is set correctly in the model editor. Unlike in many other SOF posts (including answers to this question), the suggestion to include the module name (like MyApp.Shows) has not helped me.

Make sure you check these three items:

1.
Version that works up to Xcode 7 beta 3

Up to XCode7 b3

Notice that I corrected your entity name to the more appropriate singular.

Version that works for Swift 2.0 in Xcode 7.1
(Should work for Xcode 7 beta 4 and above)

You need to delete the text "Current Product Module" in Module!

From Xcode7 beta 3

2.
You should also follow the frequent recommendation to include

@objc(Show)

just above your class.

Note: If you are using Xcode 7 beta 4 or later, this step is optional.

3.
Also make sure to cast the created managed object to the proper class, as the default would be just NSManagedObject.

var newShow = NSEntityDescription.insertNewObjectForEntityForName("Show", 
                 inManagedObjectContext: context) as Show