Create inheritable core data model in a static library - ios

I am working on a project that has a static library shippable. The static library uses core data and I succeeded to compile my core data model into a separate bundle and ship the bundle with the library as it is described for example here: core data in a static library for the iPhone.
Now my problem is that I would like to make the core data entities in the data model of the library inheritable. Thus the user could extend these entities, adding his own attributes and relationships to my base entities via core data inheritance. How could I achieve this considering that due version control purposes or package managers (I use cocoapods for the static library) it is better not to let the user modify the original core data model?
My current solution is to ship the original data model as a "template" and ask the users of the library to create a copy of it, extend it, and include only the extended data model and not the original one. But this feels somehow unprofessional and creates a mess for the users. Are there any other solutions that I am not aware of?

Related

Use of Core Data model in Widget / Today View Extension?

I’m building a Today View Extension (Widget) that needs to share data with its containing app. I use heavily core data in the containing app so I would like to use Core Data as a way of sharing a common database between both programs. It means I need to know the object graph model and all the model classes in the widget code too.
In the App Extension Programming guide, Apple says that we should use encapsulate code into Frameworks in order to share it between a containing app and a widget. But in the Framework programming guide, it’s explicitly written that Frameworks should be created only to encapsulate code that is not specific to an application but should encapsulate code that can be reused universaly.
So my questions are:
Is building a framework encapsulating all my model classes + my core data object model graph is the good way of sharing business logic between a containing app and a widget?
How would you include a whole Core Data Model into a framework as frameworks don’t seem to be designed to do that?
Based on your criteria and requirements, encapsulating your Core Data stack in an embedded framework target makes sense. I would say that it is not only a good way, but the only way without duplicating the model and logic.
I am not sure what you mean by "frameworks don’t seem to be designed to do that" in your second question. Frameworks are just another target, you should be able to create a Core Data model file whose target membership is your framework's. Then you can have some higher level method in the framework API that returns an NSManagedObjectContext based on the model included in the framework.
You are also going to be required to setup an App Group for your underlying persistent store file (typically your sqlite file). In order for your Widget and Containing App to read and write to the same file, that file must be within an App Group that both have entitlements to.

CoreData - Update model class instead of creating new

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

Set parent entity defined in bundled Core Data model

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.).

Convert existing object model to Core Data managed object model

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).

Adding objects to Core Data graphically

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.

Resources