I am using CoreData in my iOS application. I face a problem most of the times while creating NSManagedObject classes.
This is what I do:
I create an Entity in .xcdatamodeld file.
Create attributes and relationships.
Choose option Editor->Create NSManagedObject Class to create .h and .m classes.
In .h and .m classes, I create some of my custom methods for fetching/saving objects.
So far so good. But afterwards in future if I have to change some attributes, I repeat step 2 and 3. But this time all of my custom code written in step 4 are removed automatically.
So my question is how can I update the existing classes? Instead of using option Editor->Create NSManagedObject Class which removes all my custom code.
Any help is appreciated.
Update:
Tested both approaches (Categories and Mogernator) and looks fine to me. But I have choosen Categories of being a pure Xcode approach. I don't want to take the risk of any 3rd party which may break in future due to XCode updates or can cause problem of data migration.
Thanks to #Tom Harrington, and #Valentin Shamardin for guiding me :)
To make some additional methods or other stuff for your Core Data model classes you have to create Categories. This approach is used by Paul Hegarty in Core Data lections.
The best way to handle this is to use mogenerator to generate your model classes instead of having Xcode do it. With mogenerator you get two classes for each entity:
One that is re-generated every time you rebuild the model classes
One that is a subclass of the other, which is only generated the first time you build model classes and which mogenerator never changes afterward.
As a result you can put all your custom code in the subclass, and no matter how many times you re-generate your model classes, your code is never overwritten.
Whenever yo change or update your core data object model it becomes incompatible and cannot be open and as a result it gives crashes.
For this you need to perform Core Data Model Versioning and Data Migration.
Versioning is nothing just only provides you which model version is application going to use. Changes and update in core data model like modifying any attribute of entity or adding new entity. It is related with Core database model. Consider your application going to use 1.0 ver and using database model of 1. if u have some changes in database model its version increases and now you application going to use next version ie 2 of core database model
The details refer to this Apple Doc for Core Data Versioning
Also this will result in old Data loss. For this you need to perform Migration Process.
During migration, Core Data creates two stacks, one for the source store and one for the destination store. Core Data then fetches objects from the source stack and inserts the appropriate corresponding objects into the destination stack".
Please refer to Migration Process details on Migration on Raywenderlich
You need to use NSMigrationManager class and
Related
My app is working perfect for the first release v1.
In second release v2, i made a mistake while doing coredata migration - I accidentally given a renaming ID for an entity (It was empty before) in my coredata. Becuase of that the app was crashing when updating, but it is working when freshly downloading v2 version.
Now, what should i do in my next release v3, to fix this crash?
If i am replacing the renaming ID of the entity to empty, updating an app from v1 -> v2 -> v3 will be working.
But if a user freshly downloaded v2, it will get crashed again.
Please give me some workaround for this issue. Thanks in advance.
Use core data Lightweight Migration. Lightweight migration is especially convenient during early stages of application development, when you may be changing your managed object model frequently, but you don’t want to have to keep regenerating test data. You can migrate existing data without having to create a custom mapping model for every model version used to create a store that would need to be migrated.
Core Data Must Be Able to Infer the Mapping
To perform automatic lightweight migration, Core Data needs to be able to find the source and destination managed object models itself at runtime. Core Data looks for models in the bundles returned by NSBundle’s allBundles and allFrameworks methods. If you store your models elsewhere, you must follow the steps described in Use a Migration Manager if Models Cannot Be Found Automatically . Core Data must then analyze the schema changes to persistent entities and properties and generate an inferred mapping model.
For Core Data to be able to generate an inferred mapping model, changes must fit an obvious migration pattern, for example:
Simple addition of a new attribute
Removal of an attribute
A non-optional attribute becoming optional
An optional attribute becoming non-optional, and defining a default
value
Renaming an entity or property
Source : https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmLightweightMigration.html
I'm working on a static library that will help sync Core Data iOS apps with a remote SQL database. My library relies on a few sync-related attributes that each Core Data entity must have, so I've created a parent entity, SyncObject, that all other entities inherit from. SyncObject is defined in the static library's data model and is included in the resource bundle (how's my terminology?)
When I create a new app that uses this library, I merge the the app's data model with the library's data model and programmatically set all of the app's entities as sub-entities of SyncObject. Remarkably, this all works, but it feels clunky: when auto-generating entity class files, I have to manually change the base class to SyncObject (which is itself a subclass of NSManagedObject) in the .h file, and I can't define relationships between entities in the app's data model and entities in the bundled data model because the Xcode data model editor doesn't know about the entities defined in the external bundle.
Is it possible to make the editor aware of bundled data models? If so, how?
I would strongly recommend against this design. If all entities inherit from a single entity then your entire Core Data SQLite data structure will existing a single table. The performance cost for this is quite simply huge.
It is not possible to make the data modeler aware of the bundled data model.
Update
There is a difference between subclasses and sub-entities. There is nothing wrong with Subclassing. Creating sub-entities, however, is quite different and is designed to solve a different problem. Sub-entities are meant to intentionally combine so entities so that they share a common root and share a common set of properties or relationships. The cost of that is that they also share a common table. Which in the situation that they are intended for is not a significant cost.
The thread you referenced confused subclasses and sub-entities. They are not the same and they do not even need to align.
Trying to have an entire data model be sub-entities of a single parent entity is not the intended use of that feature of Core Data. It will cause horrific performance penalties and eventually stop your application from working. You would be better off working from a different design. For example, you could force them to subclass from your class which then subclasses NSManagedObject and do what you need to do in that subclass. You could further require an attribute to exist in each entity so that you can complete your goal.
mogenerator works in that vein (although it does not require an attribute to exist in the entities). There are also syncing frameworks that work off a similar design. They require that each entity have a unique identifier key, etc.
You could go even further and not necessarily require an attribute but instead require that the subclasses define a unique identifier so that you framework can uniquely identify each instance of an entity. You could then work with that uniqueID without requiring its definition be specific (a string, a number, etc.).
I am developing an iOS app and have several object models. Now I want to convert them to core data managed objects, so creating the entities and attributes from the object instead of the standard opposite way of generating the objects from the model. What is the best way to accomplish this?
I tried extending from NSManagedObject instead of NSObject, then manually creating the entities and attributes and setting up the Class name for the entity but that didn't work :-(
Thanks
I recently did this for a big project with a very large and complex data model. Here is a workflow that I found to be very feasible.
First, I create a new data model in Xcode and populate it by hand. This is a very good exercise as it forces you to review your model and perhaps take advantage of simplification opportunities.
Then, generate your class files with Xcode from the model. If you have any special code that should be included in the objects, add them as categories in separate files (e.g. Event.h & Event.m generated by Xcode, Event+Additions.h & Event+Additions.m with your code).
I have an ipad application that has a simple core data model with two entities. Eventually, I'll be adding a third entity in a update to the app. Is there anything I need to do with the current version of the data model to prepare for eventual migration?
Not really. In order for migration to work, you'll need to have both versions of the model inside the model at that point. (A model can contain multiple versions, one will be the current).
I am pretty new to using Core Data, so I'd like to ask how I graphically add items to the database I am making. With graphically I mean like in navicat I can edit things with editor.
Core Data is a object oriented framework that provides object persistence, not a visual database editor. Xcode contains a visual tool for creating and editing Core Data models, which are similar to database schemas, but there's no visual facility for managing or manipulating the data that a model describes. It can take a little while to understand Core Data; I'd suggest starting with Apple's Core Data Tutorial for iOS.
May be am not clear with the term graphically. When you start creating your model using Core data, you need to choose a data model from project resources (of type .xcdatamodel) and when you select this,it wil open a model editor for you. you can create as many entities, related attributes and establish relationships. Hope this will help you.
~Manoj.
If you just need to instantiate a new entity and add it to your data store, you'll use the method insertNewObjectForEntityForName on NSEntityDescription to create a new instance of your entity and insert it into your context. You have to call saveChanges on the context to persist that new entity to your data store. Core Data is a really powerful framework, but it isn't something most developers can just start using blindly. Read the Core Data guide, download some of the sample code, and you'll be rocking in no time.