Building Your Managed Object Model
With the project template, Xcode will create a data model file with the same name as your project. In the sample project this file is called MyMovies.xdatamodeld. To edit your data model, click the data model file, and Xcode will present the data model editor (see Figure 13.4).
Figure 13.4 Xcode data model editor, Table style.
Xcode has two styles for the data model editor: Table and Graph. The Table style presents the entities in your data model in a list on the left. Selecting an entity will display and allow you to edit the attributes, relationships, and fetched properties for that entity.
To change to Graph style, click the Editor Style Graph button in the lower-right corner of the data model editor (see Figure 13.5). There will still be a list of entities on the left of the data model editor, but the main portion of the editor will present an entity relationship diagram of your data model. Each box presented in the diagram represents an entity, with the name of the entity at the top, the attributes listed in the middle, and any relationships listed in the bottom. The graph will have arrows connecting entities that have relationships established, with arrows indicating the cardinality of the relationship.
Figure 13.5 Xcode data model editor, Graph style.
When working with your data model, it is often convenient to have more working space available and to have access to additional detail for selected items. Use Xcode’s View options in the upper-right corner of the window to hide the Navigator panel and display the Utilities panel (see Figure 13.5).
Creating an Entity
To create an entity, click the Add Entity button. A new entity will be added to the list of entities, and if the editor is in Graph style, a new entity box will be added to the view. Xcode will highlight the name of the entity and allow you to type in the desired name for the entity. The name of the entity can be changed at any time by just clicking twice on the entity name in the list of entities, or by selecting the desired entity and editing the entity name in the Utilities panel.
Core Data supports entity inheritance. For any entity, you can specify a parent entity from which your entity will inherit attributes, relationships, validations, and custom methods. To do that, ensure that the entity to be inherited from has been created, and then select the child entity and choose the desired parent entity in the Utilities panel.
Adding Attributes
To add attributes to an entity, first select the entity in either the graph or the list of entities. Then click the Add Attribute button in the lower part of the editor, just to the left of the Editor Style buttons. Xcode will add an attribute called attribute to the entity. Select a Type for the attribute. (See Table 13.1 for supported data types.) Note that Core Data treats all attributes as Objective-C objects, so if Integer 32 is the selected data type, for example, Core Data will treat the attribute as an NSNumber.
Table 13.1 Core Data Supported Data Types
Data Types |
Objective-C Storage |
Integer 16 |
NSNumber |
Integer 32 |
NSNumber |
Integer 64 |
NSNumber |
Decimal |
NSNumber |
Double |
NSNumber |
Float |
NSNumber |
String |
NSString |
Boolean |
NSNumber |
Date |
NSDate |
Binary Data |
NSData |
Transformable |
Uses value transformer |
One thing to note is that Core Data will automatically give each instance a unique object ID, called objectID, which it uses internally to manage storage and relationships. You can also add a unique ID or another candidate key to the entity and add an index to it for quick access, but note that Core Data will manage relationships with the generated object ID.
NSManagedObjects also have a method called description; if you want to have a description attribute, modify the name slightly to avoid conflicts. In the sample app, for example, the Movie entity has a movieDescription attribute.
Establishing Relationships
Having relationships between objects can be a very powerful technique to model the real world in an app. Core Data supports one-to-one and one-to-many relationships. In the sample app, a one-to-many relationship between friends and movies is established. Since a friend might borrow more than one movie at a time, that side of the relationship is “many,” but a movie can be lent to only one friend at a time, so that side of the relationship is “one.”
To add a relationship between entities, select one of the entities, and then Ctrl-click and drag to the destination entity. Alternatively, click and hold the Add Attribute button, and select Add Relationship from the menu that appears. Xcode will create a relationship to the destination entity and will call it “relationship.” In the Utilities panel, select the Data Model inspector, and change the name of the relationship. In the Data Model inspector, you can do the following:
- Indicate whether the relationship is transient.
- Specify whether the relationship is optional or required with the Optional check box.
- Specify whether the relationship is ordered.
- Establish an inverse relationship. To do this, create and name the inverse relationship first, and then select it from the drop-down.
- Specify the cardinality of the relationship by checking or unchecking the Plural check box. If checked, it indicates a to-many relationship.
- Specify minimum and maximum counts for a relationship.
- Set up the rule for Core Data to follow for the relationship when the object is deleted. Choices are No Action (no additional action taken on delete), Nullify (relationship set to nil), Cascade (objects on the other side of the relationship are deleted too), and Deny (error issued if relationships exist).
Custom Managed Object Subclasses
A custom NSManagedObject subclass can be useful if you have custom logic for your model object, or if you would like to be able to use dot syntax for your model object properties and have the compiler validate them.
Xcode has a menu option to automatically create a subclass for you. To use it, ensure that you have completed setup of your entity in the data model editor. Select your entity (or multiple entities) in the data model editor, select Editor from the Xcode menu, and then select Create NSManagedObject Subclass. Xcode will ask where you want to save the generated class files. Specify a location and click Create, and Xcode will generate the header and implementation files for each entity you specified. Xcode will name each class with the class prefix specified for your project concatenated with the name of the entity.
In the generated header file, Xcode will create a property for each attribute in the entity. Note that Xcode will also create a property for each relationship specified for the entity. If the relationship is to-one, Xcode will create an NSManagedObject property (or NSManagedObject subclass if the destination entity is a custom subclass). If the relationship is to-many, Xcode will create an NSSet property.
In the generated implementation file, Xcode will create @dynamic instructions for each entity, rather than @synthesize. This is because Core Data dynamically handles accessors for Core Data managed attributes, and does not need the compiler to build the accessor methods.