A complete listing of the main
source file for the finished tutorial is shown in Listing 8-1.
Listing 8-1 Complete listing of the main
source file
#import <Foundation/Foundation.h> |
#import <CoreData/CoreData.h> |
#include <objc/objc-auto.h> |
#import "Run.h" |
NSURL *applicationLogDirectory(); |
NSManagedObjectModel *managedObjectModel(); |
NSManagedObjectContext *managedObjectContext(); |
int main (int argc, const char * argv[]) { |
objc_startCollectorThread(); |
NSManagedObjectModel *mom = managedObjectModel(); |
NSLog(@"mom: %@", mom); |
if (applicationLogDirectory() == nil) { |
exit(1); |
} |
NSManagedObjectContext *moc = managedObjectContext(); |
NSEntityDescription *runEntity = [[mom entitiesByName] objectForKey:@"Run"]; |
Run *run = [[Run alloc] initWithEntity:runEntity |
insertIntoManagedObjectContext:moc]; |
NSProcessInfo *processInfo = [NSProcessInfo processInfo]; |
[run setProcessID:[processInfo processIdentifier]]; |
NSError *error = nil; |
if (![managedObjectContext() save:&error]) { |
NSLog(@"Error while saving\n%@", |
([error localizedDescription] != nil) ? [error localizedDescription] : @"Unknown Error"); |
exit(1); |
} |
NSFetchRequest *request = [[NSFetchRequest alloc] init]; |
[request setEntity:runEntity]; |
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] |
initWithKey:@"date" ascending:YES]; |
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; |
error = nil; |
NSArray *array = [moc executeFetchRequest:request error:&error]; |
if ((error != nil) || (array == nil)) { |
NSLog(@"Error while fetching\n%@", |
([error localizedDescription] != nil) |
? [error localizedDescription] : @"Unknown Error"); |
exit(1); |
} |
NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; |
[formatter setDateStyle:NSDateFormatterMediumStyle]; |
[formatter setTimeStyle:NSDateFormatterMediumStyle]; |
NSLog(@"%@ run history:", [processInfo processName]); |
for (run in array) { |
NSLog(@"On %@ as process ID %d", |
[formatter stringForObjectValue:run.date], |
run.processID); |
} |
return 0; |
} |
NSURL *applicationLogDirectory() { |
NSString *LOG_DIRECTORY = @"CDCLI"; |
static NSURL *ald = nil; |
if (ald == nil) { |
NSFileManager *fileManager = [[NSFileManager alloc] init]; |
NSError *error = nil; |
NSURL *libraryURL = [fileManager URLForDirectory:NSLibraryDirectory inDomain:NSUserDomainMask |
appropriateForURL:nil create:YES error:&error]; |
if (libraryURL == nil) { |
NSLog(@"Could not access Library directory\n%@", [error localizedDescription]); |
} |
else { |
ald = [libraryURL URLByAppendingPathComponent:@"Logs"]; |
ald = [ald URLByAppendingPathComponent:LOG_DIRECTORY]; |
NSDictionary *properties = [ald resourceValuesForKeys: |
[NSArray arrayWithObject:NSURLIsDirectoryKey] error:&error]; |
if (properties == nil) { |
if (![fileManager createDirectoryAtPath:[ald path] |
withIntermediateDirectories:YES attributes:nil error:&error]) { |
NSLog(@"Could not create directory %@\n%@", |
[ald path], [error localizedDescription]); |
ald = nil; |
} |
} |
} |
} |
return ald; |
} |
NSManagedObjectModel *managedObjectModel() { |
static NSManagedObjectModel *mom = nil; |
if (mom != nil) { |
return mom; |
} |
mom = [[NSManagedObjectModel alloc] init]; |
NSEntityDescription *runEntity = [[NSEntityDescription alloc] init]; |
[runEntity setName:@"Run"]; |
[runEntity setManagedObjectClassName:@"Run"]; |
[mom setEntities:[NSArray arrayWithObject:runEntity]]; |
NSAttributeDescription *dateAttribute; |
dateAttribute = [[NSAttributeDescription alloc] init]; |
[dateAttribute setName:@"date"]; |
[dateAttribute setAttributeType:NSDateAttributeType]; |
[dateAttribute setOptional:NO]; |
NSAttributeDescription *idAttribute; |
idAttribute = [[NSAttributeDescription alloc] init]; |
[idAttribute setName:@"processID"]; |
[idAttribute setAttributeType:NSInteger32AttributeType]; |
[idAttribute setOptional:NO]; |
[idAttribute setDefaultValue:[NSNumber numberWithInteger:-1]]; |
NSExpression *lhs = [NSExpression expressionForEvaluatedObject]; |
NSExpression *rhs = [NSExpression expressionForConstantValue: |
[NSNumber numberWithInteger:0]]; |
NSPredicate *validationPredicate = [NSComparisonPredicate |
predicateWithLeftExpression:lhs |
rightExpression:rhs |
modifier:NSDirectPredicateModifier |
type:NSGreaterThanPredicateOperatorType |
options:0]; |
NSString *validationWarning = @"Process ID < 1"; |
[idAttribute setValidationPredicates:[NSArray arrayWithObject:validationPredicate] |
withValidationWarnings:[NSArray arrayWithObject:validationWarning]]; |
[runEntity setProperties: |
[NSArray arrayWithObjects: dateAttribute, idAttribute, nil]]; |
NSMutableDictionary *localizationDictionary = [NSMutableDictionary dictionary]; |
[localizationDictionary setObject:@"Date" |
forKey:@"Property/date/Entity/Run"]; |
[localizationDictionary setObject:@"Process ID" |
forKey:@"Property/processID/Entity/Run"]; |
[localizationDictionary setObject:@"Process ID must not be less than 1" |
forKey:@"ErrorString/Process ID < 1"]; |
[mom setLocalizationDictionary:localizationDictionary]; |
return mom; |
} |
NSManagedObjectContext *managedObjectContext() { |
static NSManagedObjectContext *moc = nil; |
if (moc != nil) { |
return moc; |
} |
moc = [[NSManagedObjectContext alloc] init]; |
NSPersistentStoreCoordinator *coordinator = |
[[NSPersistentStoreCoordinator alloc] |
initWithManagedObjectModel: managedObjectModel()]; |
[moc setPersistentStoreCoordinator: coordinator]; |
NSString *STORE_TYPE = NSXMLStoreType; |
NSString *STORE_FILENAME = @"CDCLI.cdcli"; |
NSError *error = nil; |
NSURL *url = [applicationLogDirectory() URLByAppendingPathComponent:STORE_FILENAME]; |
NSPersistentStore *newStore = [coordinator addPersistentStoreWithType:STORE_TYPE |
configuration:nil |
URL:url |
options:nil |
error:&error]; |
if (newStore == nil) { |
NSLog(@"Store Configuration Failure\n%@", |
([error localizedDescription] != nil) ? |
[error localizedDescription] : @"Unknown Error"); |
} |
return moc; |
} |
Complete listings of the declaration and implementation of the Run class for the finished tutorial are shown in Listing 8-2 and Listing 8-3 respectively.
Listing 8-2 Listing of the declaration of the Run class
#import <Foundation/Foundation.h> |
#import <CoreData/CoreData.h> |
@interface Run : NSManagedObject { |
NSInteger processID; |
} |
@property (retain) NSDate *date; |
@property (retain) NSDate *primitiveDate; |
@property NSInteger processID; |
@end |
Listing 8-3 Listing of the implementation of the Run class
#import "Run.h" |
@implementation Run |
@dynamic date, primitiveDate; |
- (void) awakeFromInsert { |
// set date to now |
self.primitiveDate = [NSDate date]; |
} |
- (NSInteger)processID { |
[self willAccessValueForKey:@"processID"]; |
NSInteger pid = processID; |
[self didAccessValueForKey:@"processID"]; |
return pid; |
} |
- (void)setProcessID:(NSInteger)newProcessID { |
[self willChangeValueForKey:@"processID"]; |
processID = newProcessID; |
[self didChangeValueForKey:@"processID"]; |
} |
- (void)setNilValueForKey:(NSString *)key { |
if ([key isEqualToString:@"processID"]) { |
self.processID = 0; |
} |
else { |
[super setNilValueForKey:key]; |
} |
} |
@end |
Last updated: 2010-05-24