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

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.

Related

No NSEntityDescriptions in any model claim the NSManagedObject subclass

I am new to CoreData and I'm trying to create a caching mechanism wherein after parsing objects from the API, I save them to the data model then fetch it again to show it on the tableview. I'm trying to fetch it using NSFetchedResultsController. Upon initialization of the NSFetchedResultsController, I'm encountering this runtime exception:
2018-12-09 15:03:20.493509+0800 [5184:148001] [error] error:
No NSEntityDescriptions in any model claim the NSManagedObject subclass
'Product' so +entity is confused. Have you loaded your
NSManagedObjectModel yet ?
CoreData: error: No NSEntityDescriptions in any model claim the
NSManagedObject subclass 'Product' so +entity is confused. Have you
loaded your NSManagedObjectModel yet ?
2018-12-09 15:03:20.493718+0800[5184:148001] [error] error: +
[Product entity] Failed to find a unique match for an
NSEntityDescription to a managed object subclass
CoreData: error: +[Product entity] Failed to find a unique match for an
NSEntityDescription to a managed object subclass
What could be the reason why?
If you ever encounter an issue similar to this using SwiftUI, you can try changing the entity's class module from Global Namespace to Current Product Module.
Go to your xcdatamodeld file and select the problematic entity. Then in the data model inspector, change the Module field from the default Global namespace to available value "Current Product Module" by clicking on the arrow at the right of the field.
This allowed my app to compile without encountering the error.
My experience:
The entity class was missing the #objc(Person) line above the class name.
I do have more classes that are working without this line but only when creating this specific entity, I have got this error.
#objc(Person)
public class Person: NSManagedObject {
}
I came across the same issue when I changed the Codegen property of a Core Data Model to the type Category/Extension, to create a custom class for the Core Data Model.
As pointed out by #dypbrg, changing the following code segment
Product.fetchRequest()
to the following code segment
NSFetchRequest<Product>(entityName: "Product")
seems to solve the issue.
In my case I was using it SwiftUI the NSManagedObjectContext was being used before persistent store async function returned.
I then followed the core data sample project with Xcode to solve the issue:
#main
struct TestCoreDataApp: App {
//Inside the PersistenceController initialiser the store is loaded, so gives it time before passing the context to the SwiftUI View
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
In my case, I had changed the name of an entity and the swift-class but had forgot to update to the new swift-class name in the xcdatamodeld.
(In xcdatamodel view, under "CONFIGURATIONS" in the left pane, select "Default" and make sure the name of the classes are correct.)
For anyone who has this problem with hybrid projects (Obj-C + Swift).
In my case, CoreData xcdatamodel is delivered as an asset inside SPM package and is used inside this package. With Swift projects there are no problems but with hybrid one I faced the same issue.
The solution that solved my problem:
use #objc annotation for NSManagedObjects as mentioned by #Sam
#objc(Entity)
public class Entity: NSManagedObject {
}
Use Global namespace instead of Current Product Module for each entity (check #Pomme2Poule's answer how to do that)
For me, I had not named the NSPersistentContainer in the AppDelegate the same as the xcdatamodelId I had created.
let container = NSPersistentContainer(name: "DataModel")
I've encounter same issue and finally locate the root cause at persistentContainer lazy initilaize.
In AppDelegate.swift, remove lazy works for me.
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentCloudKitContainer = {...}

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.

CoreData creating an NSManagedObject Subclass with a Parent Entity

We have an app in Swift that has 10-12 data models. The developer who set them up generated them in the .xcdatamodeld file and I've since wrote extensions for them.
I've gotten to the point in the app where I realized that he had failed to generate a subclass for one of the data models named "Files". I tried adding it using the Editor -> Create NSManagedObject Subclass, and upon the wizard's completion, no error appears, but the subclass also does not appear. Assuming it might be a bug in XCode, I wrote my own Files subclass following the format of the others. Its pretty basic:
import Foundation
import CoreData
class Files: NSManagedObject {
#NSManaged var localUrl: String
#NSManaged var remoteUrl: String
#NSManaged var type: String
#NSManaged var translationFromAudio: NSSet
#NSManaged var translationToAudio: NSSet
}
Following this I went along parsing the JSON for our project and pushing the data into coreData
let entityDescription: AnyObject = NSEntityDescription.entityForName("Files", inManagedObjectContext: context)!
var request = NSFetchRequest(entityName: "Files")
request.predicate = NSPredicate(format: "remoteUrl == %#", urlString)
var file:Files
var results = context.executeFetchRequest(request, error: nil)! as NSArray
if results.firstObject != nil{
file = results.firstObject as Files
}else{
file = Files(entity: entityDescription as NSEntityDescription, insertIntoManagedObjectContext: context)
}
file.remoteUrl = audioString
file.type = "Institutional"
//All the other properties on a file are optional, so I did not include them
All works fine and dandy (this is the same format we used to save everything else into CoreData just with File's properties substituted in) The context.save() is ran after all parsing is complete to speed up the app, but it is called.
The crazy stuff starts happening when I try and run a FetchRequest to get all the Files from coreData. It comes back as 0 objects, but all the other coreData models come back.
I then tried deleting the app off the simulator and reloading it, and upon doing this after parsing again, nothing is saved to core data at all.
I've rolled back my code twice, and carefully did everything and the same result happens. I'm guessing this could be connected to the original issue of the Files subclass not generating properly. Any info on how to refresh your subclasses, or ideas on what I could be doing wrong are appreciated, I'm fairly new to Swift and XCode, so everything is still very new to me. Thanks!
EDIT
The solution below fixed my original problem, but I am left with two new issues:
Why can't I auto-generate subclasses from the menu Editor->Create NSManagedObject Subclass.
How should I format my subclass "Files" to inherit from a parent entity as the original functionality dictated.
So, I've fixed it, and with the fix created more questions.
In the entity editor, I selected the entity "Files", and in the Entity menu on the right hand side (the third tab on the righthand menu, I noticed that the Parent Entity Dropdown, had a parent entity selected, whereas all the others had "no parent entity". Upon doing this, deleting my app off the simulator and refreshing, functionality was restored and CoreData resumed its normal function.
This has opened two follow up questions:
1. Why can't I auto-generate subclasses from the menu Editor->Create NSManagedObject Subclass.
2. How should I format my subclass "Files" to inherit from a parent entity as the original functionality dictated.

Unable to find specific subclass of NSManagedObject

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.

Resources