Retired Document
Important: This document describes behavior on old releases of OS X and no longer represents best practices for OS X v10.8 and later or iOS 6 and later.
Creating the Managed Object Model
This chapter specifies the Run entity and shows you how to create the managed object model. Although it is typically easiest to create the model in Xcode, in this tutorial you create the model entirely in code.
Xcode has a data modeling tool that you typically use to define the schema for your application (see Xcode Tools for Core Data for full details). The Xcode data modeling tool is analogous to Interface Builder in that it allows you to graphically create a complex graph of objects that is archived and at runtime is unarchived. Creating a user interface without Interface Builder is possible, but can require a lot of effort. Similarly, even a reasonably straightforward model requires a lot of code, so this tutorial only uses a single entity with two simple attributes.
Specifying the Entity
The Run entity has two attributes, the process ID and the date on which the process was run. Neither attribute is optional—that is, each must have a value if an instance is to be considered valid (and if you try to save an instance without a value, you will get a validation error). The process ID has a default value of -1
. In conjunction with the validation rules, this ensures that the value is properly set at runtime. You must also specify the class that will represent the entity in the utility—in this example you will use a custom class named “Run”.
Name | Type | Optional | Default Value | Minimum Value |
---|---|---|---|---|
date | date | NO | ||
processID | int | NO | -1 | 0 |
Create the Managed Object Model
You could create the model in Xcode, put it in the application support directory, and load it at runtime using NSManagedObjectModel’s initWithContentsOfURL:
. This example, however, illustrates how to create the model entirely in code. The managedObjectModel
function creates the Run entity and its associated attributes, then creates a managed object model instance and adds the Run entity to it. For a additional layer of polish, it also adds a localization dictionary to the model—using a localization dictionary means that any log messages associated with the model are typically easier to understand.
Declare and Implement the managedObjectModel Function
The managedObjectModel
function is used in the main function, but implemented after the main function; you should therefore provide a forward declaration of the managedObjectModel
function.
At the top of the main source file, before the
main
function, add a declaration for the function.NSManagedObjectModel *managedObjectModel();
The next step is to declare and create a stub implementation of the managedObjectModel()
function. The function should determine whether the managed object context instance already exists. If it does, simply return it, if it doesn’t, create it and then configure the remainder of the stack.
In the main source file, begin the implementation of the
managedObjectModel
function.The function declares a static variable (
mom
) for the model itself, and returns the variable immediately if it is notnil
. The function should ultimately returnmom
—the next steps will create the model and the entity it contains.Add the following code:
NSManagedObjectModel *managedObjectModel() {
static NSManagedObjectModel *mom = nil;
if (mom != nil) {
return mom;
}
// Implementation continues...
return mom;
}
You should enter the code described in the following sections (Create the Run Entity, Add the Attributes, Create the Model, and Add a Localization Dictionary) immediately before the return statement (where the comment states, “Implementation continues...”).
Create the Run Entity
The first step of creating the model is to create the Run entity, represented by an instance of NSEntityDescription
. The entity description specifies both the name of the entity and the name of the class that will be used to represent instances of the entity at runtime. In this case, both names are “Run”.
Add the Attributes
Attributes are represented by instances of NSAttributeDescription
. You must create two instances—one for the date, the other for the process ID—and set their characteristics appropriately. Both require a name and a type, and neither is optional. The process ID has a default value of -1
. You also need to create a predicate for the process ID validation.
Create the date attribute description—its type is
NSDateAttributeType
and it is not optional.Add the following code:
NSAttributeDescription *dateAttribute = [[NSAttributeDescription alloc] init];
[dateAttribute setName:@"date"];
[dateAttribute setAttributeType:NSDateAttributeType];
[dateAttribute setOptional:NO];
Create the process ID attribute description—its type is
NSInteger64AttributeType
, it is not optional, and its default value is-1
.Add the following code:
NSAttributeDescription *idAttribute = [[NSAttributeDescription alloc] init];
[idAttribute setName:@"processID"];
[idAttribute setAttributeType:NSInteger64AttributeType];
[idAttribute setOptional:NO];
[idAttribute setDefaultValue:@(-1)];
Create the validation predicate for the process ID; the value of the attribute itself must be greater than zero.
The following code is equivalent to
validationPredicate = [NSPredicate predicateWithFormat:@"SELF > 0"]
, but this example continues the theme of illustrating the long-hand form.Add the following code:
NSExpression *lhs = [NSExpression expressionForEvaluatedObject];
NSExpression *rhs = [NSExpression expressionForConstantValue:@0];
NSPredicate *validationPredicate = [NSComparisonPredicate
predicateWithLeftExpression:lhs
rightExpression:rhs
modifier:NSDirectPredicateModifier
type:NSGreaterThanPredicateOperatorType
options:0];
Add error strings for the validation predicates.
Each validation predicate requires a corresponding error string. Typically the error string should be appropriately localized. You can either provide a localized representation here (using, for example,
NSLocalizedString
) or supply a localization dictionary for the model. The latter is shown in the next section (Add a Localization Dictionary). You provide the attribute description with an array of predicates and an array of error strings. In this case, each array contains just a single object.Add the following code:
NSString *validationWarning = @"Process ID < 1";
[idAttribute setValidationPredicates:@[validationPredicate]
withValidationWarnings:@[validationWarning]];
Add the properties to the entity.
Add the following code:
[runEntity setProperties:@[dateAttribute, idAttribute]];
Create the Model
You next create the managed object model itself and add the Run entity to it. A model can contain more than one entity, so the method to set the entities takes an array of entities.
Add a Localization Dictionary
You can set a localization dictionary to provide localized string values for entities, properties, and error strings related to the model. The key and value pattern is described in the API reference for setLocalizationDictionary:
. The string you use as the key for the error must be the same as that you specified for the corresponding validation predicate.
Create the localization dictionary and set it for the model:
Add the following code:
NSDictionary *localizationDictionary = @{
@"Property/date/Entity/Run":@"Date",
@"Property/processID/Entity/Run":@"Process ID",
@"ErrorString/Process ID < 1":@"Process ID must not be less than 1"};
[mom setLocalizationDictionary:localizationDictionary];
Test Your Code
So that you can test the implementation thus far, instantiate the managed object model and log its description of the model.
Create an instance of the managed object model and log its description.
In the
main
function, within the@autoreleasepool
block, declare a variable of classNSManagedObjectModel
and assign its value to the result of invoking themanagedObjectModel
function. Print the model description usingNSLog
.NSManagedObjectModel *mom = managedObjectModel();
NSLog(@"The managed object model is defined as follows:\n%@", mom);
Build and run the project.
The project should compile without warnings. The logged description of the model file should contain the entity and attributes you defined. At this stage the model has not yet been used, so its
isEditable
state remains true.
Complete Listing
The complete listing of the managedObjectModel
function is shown in Listing 2-1.
Listing 2-1 Complete listing of the managedObjectModel
function
NSManagedObjectModel *managedObjectModel() { |
static NSManagedObjectModel *mom = nil; |
if (mom != nil) { |
return mom; |
} |
NSEntityDescription *runEntity = [[NSEntityDescription alloc] init]; |
[runEntity setName:@"Run"]; |
[runEntity setManagedObjectClassName:@"Run"]; |
NSAttributeDescription *dateAttribute = [[NSAttributeDescription alloc] init]; |
[dateAttribute setName:@"date"]; |
[dateAttribute setAttributeType:NSDateAttributeType]; |
[dateAttribute setOptional:NO]; |
NSAttributeDescription *idAttribute = [[NSAttributeDescription alloc] init]; |
[idAttribute setName:@"processID"]; |
[idAttribute setAttributeType:NSInteger64AttributeType]; |
[idAttribute setOptional:NO]; |
[idAttribute setDefaultValue:@(-1)]; |
NSExpression *lhs = [NSExpression expressionForEvaluatedObject]; |
NSExpression *rhs = [NSExpression expressionForConstantValue:@0]; |
NSPredicate *validationPredicate = [NSComparisonPredicate |
predicateWithLeftExpression:lhs |
rightExpression:rhs |
modifier:NSDirectPredicateModifier |
type:NSGreaterThanPredicateOperatorType |
options:0]; |
NSString *validationWarning = @"Process ID < 1"; |
[idAttribute setValidationPredicates:@[validationPredicate] |
withValidationWarnings:@[validationWarning]]; |
[runEntity setProperties:@[dateAttribute, idAttribute]]; |
mom = [[NSManagedObjectModel alloc] init]; |
[mom setEntities:@[runEntity]]; |
NSDictionary *localizationDictionary = @{ |
@"Property/date/Entity/Run":@"Date", |
@"Property/processID/Entity/Run":@"Process ID", |
@"ErrorString/Process ID < 1":@"Process ID must not be less than 1"}; |
[mom setLocalizationDictionary:localizationDictionary]; |
return mom; |
} |
Copyright © 2005, 2013 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2013-09-18