recreate NSManagedObject subclasses when the model changes in the model editor - ios

I was wondering if there was a way to update the NSMangedObject subclass after you change a property or add a field in the Core Data model editor. Sometimes I add a field, or realize that I accidentally put integer as the type instead of string, but my NSManagedObject subclass was already created. So instead of manually going in and adding those fields, I was wondering if there was a way for Xcode to just update the model? Thanks.

Others have explained how you can re-create the files, but do notice that the files overwrite the original ones, so if you have made any manual additions (extra methods, for instance) you're going to lose them. A backup can be useful before you write the files out again.
If you do need to add functionality to an NSManagedObject subclass, consider using categories in separate files. That way you can tweak your class in the Core Data editor, re-export your files and avoid losing your additional functionality because it is saved in the category files.

I believe you just have to go to file -> new -> file -> core data under iOS -> NSManagedObject subclass and it is self explanatory from there.
You can also check out mogenerator, an open api that helps manage a lot more of core data for you.

Related

Core Data Xcode 8

I started new project without core data checked and then I tried to put it in manually. So everything is fine but I have a question concerning Codegen in Data Model Inspector.
When I put class definition in Codegen field my class was redefined in appropriate to core data way so I deleted my old one. And after I saw extension of this new class where I could find all the properties.
So after I closed I couldn't find it in my project but I want to see it again.
How can I make it appear again?
When an NSManagedObjectModel is configured to generate code, it doesn't add that code to your project. Rather, it generates that code into your Derived Data, in the DerivedSources directory for the target the model is a part of.
In Objective-C, you can just use #import "ModelName+ManagedObjectModel.h" in your other code to gain access any of the entities for which code has been generated. In Swift, you don't even need to do that, you can just use the classes that were generated.
If you want to see the code for those classes, you can use Open Quickly (command-shift-O) and type in one of the class names. Xcode should take you right to the generated source code for it.

Adding Realm objc files inside own static framework

I am creating framework in ObjC first time.
I want to store data inside realm dynamically. i.e. I have JSON for schema and data, and want to create classes, it's properties, objects, etc dynamically.
I have gone through their example code, they have provided DynamicTests.m where they have created data dynamically but I don't get it correctly.
Now I have few concerns and doubts.
What files/Folders should I include to create realm database at runtime? (ie. script folder, configuration Folder, swift folder, core folder?).
How to create dynamic schema and classes with their properties?
Is there any limitation or precaution that I should keep in my mind?
Good questions!
What files/Folders should I include to create realm database at runtime? (ie. script folder, configuration Folder, swift folder, core folder?).
Realm is no different than any other framework in this regard. When building a static framework that depends on another static framework, statically link the dependent framework all you'll be all set. No additional files are required.
How to create dynamic schema and classes with their properties?
By importing the Realm.Dynamic module, you can construct RLMProperty , RLMObjectSchema and finally RLMSchema instances which you can then pass in to RLMRealmConfiguration.customSchema. Also make sure to set the RLMRealmConfiguration.dynamic property to YES.
Is there any limitation or precaution that I should keep in my mind?
The dynamic APIs are a bit verbose and not included in the HTML API documentation, so you're using Realm in "expert" mode ;). That being said, the Realm team is happy to help with any issues you might encounter (I work at Realm).

Core Data Entity rename

I created a Core Data Entity called "MyObject". I then renamed the entity "ThatObject". But every time I create a NSManagedObject subclass, it still creates the .h/.m file as MyObject.
I take the "MyObject" files and just rename them to "ThatObject" and everything works, but its annoying to have to do that everytime i alter the entity attributes.
Any idea how to fix this?
When you are renaming the entity make sure you rename both Name and Class in the Data Model Inspector. In my project, if both are renamed the new auto-generated NSManagedObject subclasses are created with the new names.
For future readers: Pay attention to the model version though, if your app is already published, updating the app may break the database schema on your users devices which results in a crash on launch. Core Data can automatically find a migration for this easy case, you can find more information on lightweight migrations here. You basically have to set a renaming ID so CD knows what got renamed to what even if skipping versions in between.

Better way to recreate the class definition after modifying core data model?

When designing the core data model in XCode, you can automatically generate NSManagedObject subclass definitions (.m and .h files) by
Selecting the Entities
Choosing "Create NSManagedObject Subclasses" from EDITOR menu
After that, you may add a lot of code in these classes, what if you have to modify the data model setting a lot for some reason after that? To reflect these changes on the data model, is there any automatic way to do that? or you have to do everything manually.
Currently if I try to recreate these class definition from EDIT menu again(automatically), it will replace all the current files. All added code will disappear.
I really hope future version of Xcode can add a smart feature: automatically updating the default class definition without losing the added work. Maybe I am too lazy. :)
You're running into a common problem. You're pretty much stuck with that way of creating managed object subclasses with Xcode for the time being. Knowing that, you can either:
Design around it
For simple cases, you can use Categories to add functionality (though not state) to your NSManagedObject subclasses. Code in the category's file is obviously safe from being overwritten every time your data model changes.
Don't use Xcode
Mogenerator is a nifty tool designed to solve exactly that problem. It creates two classes for each entity instead of one, allowing Xcode to manage one while you manage the other.
It seems Apple has addressed the issue with XCode 7 : now it automatically creates the entity and a category of the entity with its core data properties. When you regenerate, it only updates the category, leaving your custom code in the entity class unharmed. See this link
You can create a class with different name and paste the generated fields into the old class

Using one xcdatamodelId in two app

I created one project with core data that will work with unchangeable database. And I don't want to write code in this project , that will programmatically populate this database. So, I create second project with core data, add existing xcdatamodel from first project without copying(only references). There i populate my database, open it with mozilla plug-in and it successfully filled. Then I copy ,my *.sqlite file and manually replace it with old file in first project. It causes error:"The model used to open the store is incompatible with the one used to create the store". But I use for both files the same xcdatamodelid. Where my error?
Sorry for my english, I really need help.
P.S. when I open sqlite file from first project and second (with commented code of populate base) in FileMerge - second is already empty. I appreciate any advice or help.
Karoly S nicely answers the question. I have a hint that I frequently employ that may prevent this out of sync situation. Instead of two Xcode projects trying to share one model file, just create one Xcode project with two targets. Each target will use the same model file, any class definitions derived from that model, and possibly other code. My second target is a Mac OS command line program that generates the database, while my first target continues to be the iOS app that reads that database. The Mac OS target will overwrite the database file in a project subdirectory, ensuring it's up-to-date. If I make any changes to the model, Xcode knows to update both targets.
Did you change your Model Definitions in any way? The error you are seeing is because there is some difference between the model from when you created it, and again from when you are trying to reference it. Are you running on the simulator? Try to delete both of your apps to clear the data related to it, as it might be out of date. Afterwards simply rebuild both of your projects as that will update your core data database.
EDIT: To clarify a bit more, your core data model is out of sync, this is generally caused by you building and running an app, and a database being created, then redefining your object model, this can be done in a variety of ways, most likely caused by the addition of an attribute or entity. So when you are trying to load the database there are fields that the app and core data are looking for, but are not there because they did not exist when the database was created. I hope this helps.

Resources