How to get Entity Name in coredata - ios

I have first project that dealing with coreData. I followed this tutorial. Everything was fine until I created new project with new core data models that has same fields and same structure to have deeper understand. However, I couldn't figure out where the variable self.entityName in class SDDateTableViewController.m got assigned value. Because the variable self.entityName in my new project is getting nil in method -(void)loadRecordsFromCoreData in SDDateTableViewController.m class.
Note: I did try copy every single line of code to my project, but the variable self.entityName is still nil
Please help me explain this issue.

It is define in the Storyboard on the SDDateTableViewController scene on "User defined runtime attributes".

Related

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.

NSManagedObject cannot change attribute

I am running into an issue with CoreData (using MagicalRecord) trying to change an attribute. I think this is the result of the object having relationships to two parent entities.
The object is a manual, this has a to-many relationship to both a car and library. The library contains all manual objects. A car has 1-3 manual items.
Every manual has a UID and the same object is shared between the car and library.
For some reason, once the object is set into the relationship for both, I cannot change the title (NSString) attribute of the manual.
I checked to make sure I am in the same context. Not sure what the issue is.
This is what I am logging:
NSLog(#"Manual Title: %#",manual.title);
//prints Old Manual
manual.title = #"New Manual"
NSLog(#"Manual Title: %#",manual.title);
//prints New Manual
I'm saving this inside a MagicalRecord saveUsingCurrentThreadContextWithBlockAndWait other unrelated NSManagedObjects in the same method are being saved.
When the app loads the data into the UI, it still reads "Old Manual"
Any suggestions?
Thank you for your time.
It turns out the issue was two-fold with the MagicalRecord methods I was using:
1) Instead of saveUsingCurrentThreadContextWithBlockAndWait I should have used saveWithBlockAndWait
2) When I was fetching the manual object, I wasn't passing the context, so I changed MR_findFirstWithPredicate to MR_findFirstWithPredicate:inContext
Hopefully this will save someone else some time

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.

Exception when calling insertInManagedObjectContext:

I am creating a Reddit client for iOS for learning purposes. I am using CoreData, which I set up by following the CoreData Basics NSScreencast and I used Mogenerator to generate the model files.
I added a breakpoint to catch all exceptions and when I call the insertInManagedObjectContext: class method provided by Mogenerator, the app crashes on the following line:
return [NSEntityDescription insertNewObjectForEntityForName:#"AZRedditAccount" inManagedObjectContext:moc_];
This line is in the model that Mogenerator generated (_AZRedditAccount). When I look at the Variables View, I noticed an odd line which I don't really understand...
What do I need to do to make things work please?
Edit: Here is what I have in my .xcdatamodeld file:
Edit 2: I added the whole project to Github, thought it might help solve the problem: https://github.com/AzizLight/Reddit
If you debug you see that your ManagedObjectContext (MOC) has no assigned PersistentStoreCoordinator (PSC) and therefore not model. In AZRedditDataModel.m you're initializing the PSC, but you're not retaining it (lines 84-109). If there's no model, the context cannot create any entities, because there's no "blueprint".

Core Data Error

I'm following this book tutorial to learn core data (Apress Pro Core Date for iOS 2nd Edition). And I thought I was following correctly but I ran into an error I dont know how to solve. The code is posted here.
I'm interested not only in the correction to the problem, but the steps you took to find out what the problem is.
The error message is "Cannot create an NSPersistentStoreCoordinator with a nil model", so that indicates there's something wrong with your managedObjectModel method.
First off, you named your model file as "Model", but the method is looking for one called "OrgChart", so either rename your model file or change the name in the managedObjectModel method.
Afterwards, it still doesn't work and setting a breakpoint in the managedObjectModel method reveals that it is actually never called. That's because you have a typo there, you've called the method mangedObjectModel instead of managedObjectModel. After adding the missing a, your app should run.

Resources