Unable to find specific subclass of NSManagedObject - ios

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:

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:
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".

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.

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

Remember to remove your module:

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
}()

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"

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.

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.

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.

By the way be careful 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!!!

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.

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.

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.

Related

How to fix "An NSManagedObject of class 'ClassName' must have a valid NSEntityDescription" when using CoreData from a framework

I have separated my Data Access Layer (DAL) in a framework in order to be able to use it in both the app and its Today widgets. I set up everything and it compiled but at runtime when I tried to create a NSPersistentContainer the app crashed with the infamous An NSManagedObject of class 'ClassName' must have a valid NSEntityDescription.
What I tried:
checking if the name of the persistent container is the same as the data model
selecting Current Product Module for the model class module
What helped:
checking all targets that will use CoreData for the xcdatamodeld file
To do this:
Select the xcdatamodeld file in Project Navigator
Open Utilities on the right side
Open File Inspector
Check all needed targets under Target Membership
I also faced the same issue while moving the data layer to a framework. The issue is NSPersistentContainer looks for an entity description in the main bundle by default, unless we create a custom subclass.
So the solution is to create a custom subclass of NSPersistentContainer in the embedded framework, and use it instead of the parent class. It should solve the problem.
In My case it was fixed when I changed
let container = NSPersistentContainer(name: "Your Project Name Here")
to
let container = NSPersistentContainer(name: "Your Data Model Name Here")
In Appdelegate.Swift

Xcode-beta 8. Can't create core data

I have been trying to add core data.
And every time I got the same error:
error: filename "EntityName +CoreDataClass.swift" used twice: '/Users/userName/Desktop/Development/MyApp/AppName/EntityName +CoreDataClass.swift' and '/Users/userName/Library/Developer/Xcode/DerivedData/AppName-dgwzrmxsetzvtedibxrazuutjwnh/Build/Intermediates/AppName.build/Debug-iphoneos/AppName.build/DerivedSources/CoreDataGenerated/Model/EntityName +CoreDataClass.swift'
I add core data using the following steps:
1.New file/ DataModel; save it in the root dir of my project
select Model.xcdatamodeld and add entity, add several attributes, save,
editor/create NSManagedObjectClass Subclass.
As a result I observe 4 new files in navigator:
Model.xcdatamodeld, EntityName+CoreDataProperties.swift, EntityName +CoreDataClass.swift, _COREDATA_DATAMODELNAME_+CoreDataModel.swift
their content:
_COREDATA_DATAMODELNAME_+CoreDataModel.swift:
import Foundation
import CoreData
___COREDATA_DATAMODEL_MANAGEDOBJECTCLASSES_IMPLEMENTATIONS___
EntityName +CoreDataClass.swift:
import Foundation
import CoreData
class EntityName: NSManagedObject {
}
EntityName+CoreDataProperties.swift:
import Foundation
import CoreData
extension EntityName {
#nonobjc class func fetchRequest() -> NSFetchRequest< EntityName > {
return NSFetchRequest< EntityName >(entityName: "EntityName");
}
#NSManaged var str: String?
}
What I have tried:
1. Clean build, remove DerivedData, delete content of var/folders, restart
2. Delete generated files, displayed in navigator
All my efforts were out of luck.
What I am doing wrong?
There are two bugs in XCode 8 here:
1 - If you change the Codegen dropdown, it's new value isn't saved in Model.xcdatamodel. You have to change something else to get it to save. For example change the class name; build; change the class name back; build again.
2 - The generated code is placed in DerivedData in the Intermediates folder, but it only happens if the folder doesn't already exist. The workaround is to do a clean then a build.
Xcode 8 includes automatic NSManagedObject class generation when the model file uses the Xcode 8 file format. If you create your own subclass files, you're creating duplicates. The second file in the error message, in DerivedSources, is the one that Xcode created automatically.
If the automatically generated files do what you need, just stop creating your own and you'll be OK.
If you want to create your own subclasses instead, you can either
Set the "tools version" for the model file to be Xcode 7.3 or earlier to disable all code generation (this doesn't seem to change anything meaningful about the actual file contents), or
Disable automatic generation for each entity individually by setting the "Codegen" setting to "Manual/None" for the entity.
I'm actually having the same problem (using Swift) and suspect it is a bug. If I understand correctly the OP is using Xcode's autogen NSManagedObject subclasses and is not then subsequently creating additional (superfluous) subclasses which appears to be a source of some confusion.
Steps to reproduce:
Create a new project, single view application. Tick "Use Core Data'
Create an entity in the model entity, add properties, ensure file is
saved (sometimes Xcode 8 Beta throws the data if not explicitly
saved)
Select Editor -> Created NSManagedObject subclass. Tick relevant
boxes
Xcode creates 3 files:
COREDATA_DATAMODELNAME_+CoreDataModel.swift. This file is
corrupted and contains non-valid entries following statements to
import Foundation and CoreData - the project will not compile unless
this file is deleted
import Foundation
import CoreData
___COREDATA_DATAMODEL_MANAGEDOBJECTCLASSES_IMPLEMENTATIONS___
EntityName+CoreDataClass.swift
EntityName+CoreDataProperties.swift
Although the editor doesn't flag any errors at this point, attempts to compile fail for the reasons listed by the OP (namely missing files with the same names but with a '.' prefix in the DerivedData folder)
If you create the NSManagedObject subclasses manually after creating your model without using Xcode's evidently bugged auto-gen, there are no issues. A bit more typing but a lot more reliable! However, you will need to start from a 'clean' project (i.e. before you attempted to auto-generate the subclasses) otherwise the error persists. Cleaning out Derived Data won't help sadly.
***** UPDATED *****
There does appear to be something rather odd going on and there does appear to be silent code generation as originally suggested (apologies) but this is very different behaviour from what one would expect. Furthermore, this code is not visible in the editor (which seems a little pointless as well as confusing). It is created in a subfolder of DerivedData > Build > Intermediates > .Build.
I can completely see why the OP was confused (as was I!) For what it's worth this 'feature' is undoubtedly an attempt to be helpful but is somewhat confusing if you're used to previous behaviour and you are offered an option to generate a visible and editable duplicate from the main menu.
So, select 'Manual/None' in the Codegen window (shown below) and then you can either use the auto-gen option in the menu bar (after deleting the 'junk') or write your own code.
Follow these steps,
Disable automatic generation for each entity individually by setting
the "Codegen" setting to "Manual/None" for the entity.
Change entity name to something else to get it to save. For example
change the class name; build; change the class name back; build
again.
I got this error to,
just the change the tool version to Xcode 7.3 in your file .xcdatamodeld
and it works fine!
For everyone having trouble getting autogen to work:
I had to set the "com.apple.syncservices.Syncable" to "NO" on the User Info settings for the Entity.
Maybe that helps out.
Tom Harrington Answer is correct. However, there is a way to add your own functions and/or vars without doing any of the two mentioned options.
Just create an extension to the class. (make sure you name the swift file something different than the standard auto-generated NSManagesObject files.)
For example. If you have an entity called MyEntity you could add a swift file called MyEntityExtension.swift which could look something like this:
import Foundation
import CoreData
import UIKit
extension MyEntity {
var color: UIColor {
get {
return self.colorValue as! UIColor
}
set {
if newValue.isMember(of: UIColor.self) {
self.colorValue = newValue
}
}
}
}
After trying a handful of posted answers, rebooting my machine worked for me.
Delete compile file core data in the tab "Build phases" section "Compile source" pressed -

Core data Issues with SpriteKit [duplicate]

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...
})
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
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!
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
SWIFT 2 / XCODE 7 Update:
This issue (see my April 3 comment on this answer as well) is resolved in Swift 2 and XCode 7 beta release by Apple.
So you actually now do not need #objc(myEntity) in Swift as answered by Mundi or using
"MyAppName." before your Class name. It will stop working. So remove these, just put Class name in File and select Current Working Module as Module
and cheers!
But for those using #objc(myEntity) in Swift (like me), you can use this other solution instead which works smoothly.
In the xcdatamodel correct class in. It should look like this:
Here you go. Module.Class is the pattern for CoreData in Swift and XCode 6. You will also need the same procedure when using Custom Policy class in Model Policy or other CoreData stuff. A note: In image, The Name and Class should be Car and MyAppName.Car (or whatever the name of your entity). Here, User is a typo.
When using Xcode 7 and purely Swift, I actually had to remove #objc(MyClass) from my auto-generated NSManagedObject subclass (generated from Editor > Create NSManagedObject Subclass...).
In Xcode 7 beta 2 (and I believe 1), in the model configuration a new managed object of type File is set to the Module Current Product Module and the class of the object is shown in configuration as .File.
Deleting the module setting so it is blank, or removing the full stop so the class name in configuration is just File are equivalent actions, as each causes the other change. Saving this configuration will remove the error described.
In Xcode 6.1.1 you do not need to add the #objc attribute since the base entity is a subset of an objc class (NSManagedObject) (see Swift Type Compatibility. In CoreData the full Module.Class name is required. Be aware the Module name is what is set in Build Settings -> Packaging -> Product Module Name. By default this is set to $(PRODUCT_NAME:c99extidentifier) which will be the Target's name.
With xCode 7 and Swift 2.0 version, you don't need to add #objc(NameOfClass), just change the entity settings in "Show the Data Model Inspector" tab like below -
Name - "Your Entity Name"
Class - "Your Entity Name"
Module - "Current Product Module"
Code for Entity class file will be like (in my code Entity is Family) -
import UIKit
import CoreData
class Family: NSManagedObject {
#NSManaged var member : AnyObject
}
This example is working fine in my app with xCode 7.0 + swift 2.0
Do not forget to replace PRODUCT_MODULE_NAME with your product module name.
When a new entity is created, you need to go to the Data Model Inspector (last tab) and replace PRODUCT_MODULE_NAME with your module name, or it will result a class not found error when creating the persistent store coordinator.
You also need to use (at least with Xcode 6.3.2) Module.Class when performing your cast for example:
Assuming your module (i.e. product name) is Food and your class is Fruit
let myEntity = NSEntityDescription.entityForName("Fruit", inManagedObjectContext: managedContext)
let fruit = NSManagedObject(entity: myEntity!, insertIntoManagedObjectContext:managedContext) as! Food.Fruit
Recap:
Include module name when defining entity in Data Model Editor (Name: Fruit, Class: Food.Fruit)
When accessing the entity in code (i.e.SWIFT), cast it with Module.class (e.g. Food.Fruit)
I also encountered a similar problem, follow these steps to resolveļ¼š
The parent is NSManagedObject, not NSObject
The module of an
entity is default, not "Current Product Module"
Changing the Entity Class name in the Data Model editor to correspond to the class in question and adding #objc(NameOfClass) to file of each NSManagedObject right above the class declaration solved this problem for me during Unit Testing.
Most of these answers still seem to apply in Xcode 14. However, my Swift NSManagedObject subclass is included in a custom framework. So what worked for me is: In that Entity inspector, in that Module field (see screenshot in answer by khunsan), type in the name of your framework, for example, MyFramework.
What worked for me (Xcode 7.4, Swift) is changing the class name to <my actual class name>.<entity name>
in the Entity inspector, 'Class' box.
My initiator of the Managed object subclass, looks like this:
convenience init(<properties to init>) {
let entityDescr = NSEntityDescription.entityForName("<entity class name>", inManagedObjectContext: <managed context>)
self.init(entity: entityDescr!, insertIntoManagedObjectContext: <managed context>)}
//init properties here
For Xcode 11.5: if Codegen property is class Definition, and if you are not getting a suggestion for the entity you created in xcdatamodel. Try to quit Xcode and reopen your project again. It works for me. This answer is only if you are not getting suggestions but if your file doesn't get generated try any above answer.

NSManagedObject Subclass can't be Loaded [duplicate]

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:
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:
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".
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.
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
Remember to remove your module:
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
}()
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"
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.
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.
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.
By the way be careful 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!!!
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.
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.
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.

How come I can cast to NSManagedObject but not to my entity's type?

I'm using the Swift boilerplate code for Core Data in a fresh project. My .xcdatamodeld file has a single entity defined (Task) with a single attribute (name).
I have a Task.swift file that looks like this:
import CoreData
class Task: NSManagedObject {
#NSManaged var name: String
}
When I run this, it works:
var firstTask = NSEntityDescription.insertNewObjectForEntityForName("Task",
inManagedObjectContext: managedObjectContext) as NSManagedObject
firstTask.setPrimitiveValue("File my TPS reports", forKey: "name")
var error: NSError?
managedObjectContext.save(&error)
I can even go into the SQLite database being used by the iOS simulator and confirm that the row was added.
However, when I run the exact same code as above but with as Task instead of as NSManagedObject, I get a crash with the error message Thread 1: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0), associated with the var firstTaskā€¦ line. If I continue execution, I get EXC_BAD_ACCESS and 0 misaligned_stack_error_ at the top of Thread 1 each time I advance it.
Why might this cast lead to all this?
Make sure your Class name field is actually Module.Task, where Module is the name of your app. CoreData classes in Swift are namespaced. Right now, your object is being pulled out of the context as an NSManagedObject, not as a Task, so the as-cast is failing.
This is even frustrated if you tried all the above suggestions and non of them working for me!!
So this is what works for me.
1- Select your xcdatamodeld file
2- Make sure that all your entities has No Module in the "Data Model
Inspector", if you see "Model: Current Product Module" ..clear it it so it looks like the attached image.
3- Delete your App to clear core data
4- If still not working, delete your entities and regenerate them.
You need to modify your Task.swift file. Adding #objc(Task) like below
import CoreData
#objc(Task)
class Task: NSManagedObject {
#NSManaged var name: String
}
I think this as a bug if your project does not contain any objective-c codes. However, you need to add that line until this fixed.
I learned it from here.
Youtube video at 11:45
I guess only changing the class field in the .xcdatamodel doesn't work anymore because I still got the following exception:
fatal error: use of unimplemented initializer 'init(entity:insertIntoManagedObjectContext:)' for class
So, I entered this code in my custom class:
init(entity: NSEntityDescription!,
insertIntoManagedObjectContext context: NSManagedObjectContext!) {
super.init(entity: entity, insertIntoManagedObjectContext: context)
}
Suddenly, it worked! The NSManagedObject is now down-castable to my custom class.
I can't really understand why this is the solution, but it works :)
An update for #Ben Gottlieb answer under XCode 7.1 and Swift 2.0
add #objc to your class. See Owen Zhao's answer. The following is an example:
#objc
class ImageRecordMO: NSManagedObject{
Open your .xcdatamodled file.
Select your entity and click the data model inspector on the right panel.
Enter the class name, see the figure below
Select your module to be Current Product Module, see the figure below.
Xcode 7 + Swift 2
Person.swift
#objc(Person)
class Person: NSManagedObject {
}
Data model
Then simply call
let person = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: self.managedObjectContext) as! Person
I had to add the #objc() and set the class in the coredata interface.
In the CoreData right window, in the Entity area, there are Name and Class textbox. Class must not be MSManagedObject but instead your class.
I created a simple working example!
I've run into this problem in the last few days and strangely the solution that worked for me was a variant of that suggested above.
I added the #objc declaration to the generated subclasses, but removed any namespace prefix in the class name in the object model (it had a default prefix of "PRODUCT_MODULE_NAME." after the subclasses were generated). That worked.

Resources