// // PersistentDictionary.m // // Created by Michael Heyeck on 9/8/10. // #import "PersistentDictionary.h" @interface PersistentDictionary () - (NSArray*)fetchForKey:(NSString*)key; - (void)deleteForKey:(NSString*)key; - (void)insertValue:(NSString*)value forKey:(NSString*)key; @end @implementation PersistentDictionary - (id)init { return [self initWithEntityName:nil inContext:nil]; } - (id)initWithEntityName:(NSString*)name inContext:(NSManagedObjectContext*)managedObjectContext { if (self = [super init]) { NSEntityDescription* e = nil; @try { e = [NSEntityDescription entityForName:name inManagedObjectContext:managedObjectContext]; } @catch (NSException* ne) {} if (!e) { [self release]; return nil; } moc = [managedObjectContext retain]; entity = [e retain]; } return self; } - (BOOL)hasValueForKey:(NSString*)key { NSArray* a = [self fetchForKey:key]; if (![a count]) { // Error/nonexistent pair return NO; } else { // Found a non-empty array of results associated with the key return YES; } } - (BOOL)boolForKey:(NSString*)key { NSArray* a = [self fetchForKey:key]; if (![a count]) { // On an error/nonexistent pair, default to NO return NO; } // In principle, there could be several pairs (this would be a bug); grab the first one arbitrarily // Note that on non-integer (i.e., buggy) values, this also defaults to 0 (NO) return [[[a objectAtIndex:0] valueForKey:@"value"] integerValue] == YES; } - (float)floatForKey:(NSString*)key { NSArray* a = [self fetchForKey:key]; if (![a count]) { // On an error/nonexistent pair, default to 0.0 return 0.0; } // In principle, there could be several pairs (this would be a bug); grab the first one arbitrarily // Note that on non-float (i.e., buggy) values, this also defaults to 0.0 return [[[a objectAtIndex:0] valueForKey:@"value"] floatValue]; } - (double)doubleForKey:(NSString*)key { NSArray* a = [self fetchForKey:key]; if (![a count]) { // On an error/nonexistent pair, default to 0.0 return 0.0; } // In principle, there could be several pairs (this would be a bug); grab the first one arbitrarily // Note that on non-double (i.e., buggy) values, this also defaults to 0.0 return [[[a objectAtIndex:0] valueForKey:@"value"] doubleValue]; } - (NSInteger)integerForKey:(NSString*)key { NSArray* a = [self fetchForKey:key]; if (![a count]) { // On an error/nonexistent pair, default to 0 return 0; } // In principle, there could be several pairs (this would be a bug); grab the first one arbitrarily // Note that on non-integer (i.e., buggy) values, this also defaults to 0 return [[[a objectAtIndex:0] valueForKey:@"value"] integerValue]; } - (NSString*)stringForKey:(NSString*)key { NSArray* a = [self fetchForKey:key]; if (![a count]) { // On an error/nonexistent pair, default to an empty string return @""; } // In principle, there could be several pairs (this would be a bug); grab the first one arbitrarily NSString* r = [[a objectAtIndex:0] valueForKey:@"value"]; return r?r:@""; } - (void)setBool:(BOOL)value forKey:(NSString*)key { [self deleteForKey:key]; [self insertValue:[NSString stringWithFormat:@"%d",value] forKey:key]; } - (void)setFloat:(float)value forKey:(NSString*)key { [self deleteForKey:key]; [self insertValue:[NSString stringWithFormat:@"%f",value] forKey:key]; } - (void)setDouble:(double)value forKey:(NSString*)key { [self deleteForKey:key]; [self insertValue:[NSString stringWithFormat:@"%f",value] forKey:key]; } - (void)setInteger:(NSInteger)value forKey:(NSString*)key { [self deleteForKey:key]; [self insertValue:[NSString stringWithFormat:@"%d",value] forKey:key]; } - (void)setString:(NSString*)value forKey:(NSString*)key { [self deleteForKey:key]; [self insertValue:value?value:@"" forKey:key]; } - (void)dealloc { [moc release]; [entity release]; [super dealloc]; } #pragma mark Extension methods - (NSArray*)fetchForKey:(NSString*)key { // Create a request (for edited Event) NSFetchRequest* request = [[[NSFetchRequest alloc] init] autorelease]; request.entity = entity; // Add a predicate to the request request.predicate = [NSPredicate predicateWithFormat:@"key == %@",key]; // Do a simple fetch (ignore errors) NSError* err; return [moc executeFetchRequest:request error:&err]; } - (void)deleteForKey:(NSString*)key { // Perform the delete(s) for (NSManagedObject* o in [self fetchForKey:key]) { [moc deleteObject:o]; } // Commit the change(s) NSError* err; if (![moc save:&err]) { // Handle the error. NSLog(@"Unresolved error %@, %@", err, [err userInfo]); } } - (void)insertValue:(NSString*)value forKey:(NSString*)key { // Can't associate values with nil keys if (!key) return; // Create the object NSManagedObject* o = [[[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:moc] autorelease]; // Store the KV pair [o setValue:key forKey:@"key"]; [o setValue:value forKey:@"value"]; // Commit the changes NSError* err; if (![moc save:&err]) { // Handle the error. NSLog(@"Unresolved error %@, %@", err, [err userInfo]); } } @end