Listing One shows how we might implement the database file cycle in a custom class. The class, FooTriage, declares three protected properties (lines 4-6) for three Core Data classes. In its init method (line 22), FooTriage invokes prepModel, which creates an instance of NSManagedObjectModel using initWithContentsOfURL: (lines 61-62). To that init method, it sends the path to the resource file FooTriage.momd. This file sits inside the application bundle (lines 54-56), and it contains the database schema defined earlier. The prepModel method ends by storing the NSManagedObjectModel instance into the property dbModel.
// -- Declaring the class interface
@interface FooTriage : NSObject
{
NSManagedObjectContext *dbContext;
NSManagedObjectModel *dbModel;
NSPersistentStoreCoordinator *dbSource;
}
- (void)prepModel;
- (void)link2file;
- (void)save2file;
@end
// -- Implementing the class
@implementation FooTriage
// Initialising the class
- (id)init
{
// initialise the parent
if (self = [super init])
{
[self prepModel];
[self link2file];
return (self);
}
else
// the parent failed to initialise
return (nil);
}
// Disposing the class
- (void)dealloc
{
// save any database changes
[self save2file];
// dispose the following properties
[dbContext release];
[dbModel release];
[dbSource release];
// invoke the parent method
[super dealloc];
}
// Preparing the object model
- (void)prepModel
{
NSString *tPth;
NSURL *tURL;
// set the schema location
tPth = [[NSBundle mainBundle]
pathForResource:@"FooTriage"
ofType:@"momd"];
tURL = [NSURL fileURLWithPath:tPth];
// load the schema
dbModel = [[NSManagedObjectModel alloc]
initWithContentsOfURL:tURL];
}
// Linking to the database file
- (void)link2file
{
NSURL *tURL;
NSError *tErr = nil;
BOOL tChk;
// set the file location
tURL = [NSURL fileURLWithPath:[[self
applicationDocumentsDirectory]
stringByAppendingPathComponent:@"FooTriage.sqlite"]];
// create the coordinator
dbSource = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:dbModel];
if (dbSource != nil)
{
// initialise the coordinator
tChk = [dbSource
addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:tURL
options:nil error:&tErr];
if (tChk)
{
// prepare the object context
dbContext = [[NSManagedObjectContext alloc]
init];
[dbContext
setPersistentStoreCoordinator:dbSource];
}
else
NSLog(@"failure");
}
}
// Saving changes into the file
- (void)save2file
{
NSError *tErr = nil;
BOOL tChk;
// check for a valid context
tChk = (dbContext != nil);
if (tChk)
{
// does it have pending changes?
tChk = [dbContext hasChanges];
if (tChk)
// update the database file
tChk = [dbContext save:&tErr];
}
// check the save outcome
if (tChk)
NSLog(@"successful save");
else
NSLog(@"failed save");
}
@end
Listing One.
Next, FooTriage invokes the method link2file (line 23). This method makes an instance of NSPersistentStoreCoordinator and links it with the property dbModel (lines 78-79). It also stores the instance into the property dbSource. Then the link2file method preps dbSource with the method addPersistentStoreWithType… (lines 83-86). To that method it sends the path to the database file FooTriage.sqlite and an NSError object. When addPersistentStoreWithType… returns a YES, link2file creates an instance of NSManagedObjectContext (lines 90-91) and stores it in the property dbContext. It then connects dbContext to dbSource using the method setPersistentStoreCoordinator: (lines 92-93).
In its dealloc method (line 36), FooTriage invokes its method save2file. This method checks the property dbContext for a valid instance of NSManagedObjectContext and for any pending changes (lines 107-111). If both are true, save2file calls the save: method (line 114), passing along an NSError object for input. Afterwards, FooTriage disposes of each property with a release message and invokes its parent's dealloc method (lines 39-44).
Working with Database Records
A typical record transaction can be one of four basic tasks: retrieval, insertion, edition, and deletion. Except for retrieval, these tasks alter the database by adding new records or changing existing records. The alterations are always queued to allow for undos and to protect the database file from unwanted changes.
Listing Two shows how to prepare a constant table. This method, initInjury, adds eight records to the table Injury. It starts with a sequence of injury terms, each term delimited by a '%' token (line 11). It then uses the NSString method componentsSeparatedByString: to divide the terms and hold them in an NSArray object (line 13).
- (void)initInjury
{
NSString *tInj, *tNom;
NSUInteger tIdx, tKey, tCnt;
NSArray *tLst;
NSError *tErr = nil;
NSManagedObject *tRec;
// define the list of injuries
tInj = @"Blunt Trauma%Burn%C-Spine%Cardiac%Crushing%Fracture%Laceration%Penetration";
tLst = [tInj componentsSeparatedByString:@"%"];
tCnt = [tLst count];
// start adding the categories
for (tIdx = 0; tIdx < tCnt; tIdx++)
{
// create a new record
tRec = [NSEntityDescription
insertNewObjectForEntityForName:@"Injury"
inManagedObjectContext:dbContext];
if (tRec != nil)
{
// read an injury name
tNom = [tLst objectAtIndex:tIdx];
// prepare the record
tKey = tIdx;
[tRec setValue:[NSNumber numberWithInt:tKey]
forKey:@"id"];
[tRec setValue:tNom forKey:@"name"];
// insert the record
[dbContext insertObject:tRec];
}
}
// ...commit the records to make them available
}
Listing Two.


