How to programmatically bind to a Core Data model?
- by Dave Gallagher
Hello. I have a Core Data model, and was wondering if you know how to create a binding to an Entity, programmatically? Normally you use bind:toObject:withKeyPath:options: to create a binding. But I'm having a little difficulty getting this to work with Core Data, and couldn't find anything in Apple's docs regarding doing this programmatically.
The Core Data model is simple:
An Entity called Book
An Attribute of Book called author (NSString)
I have an object called BookController. It looks like so:
@interface BookController : NSObject
{
NSString *anAuthor;
}
@property (nonatomic, retain) NSString *anAuthor; // @synthesize anAuthor; inside @implementation
I'd like to bind anAuthor inside BookController, to author inside a Book entity. This is how I'm attempting to wrongly do it (it partially works):
// A custom class I made, providing an interface to the Core Data database
CoreData *db = [[CoreData alloc] init];
// Creating a Book entity, saving it
[db addMocObject:@"Book"];
[db saveMoc];
// Fetching the Book entity we just created
NSArray *books = [db fetchObjectsForEntity:@"Book" withPredicate:nil withSortDescriptors:nil];
NSManagedObject *book = [books objectAtIndex:0];
// Creating the binding
BookController *bookController = [[BookController alloc] init];
[bookController bind:@"anAuthor" toObject:book withKeyPath:@"author" options:nil];
// Manipulating the binding
[bookController setAnAuthor:@"Bill Gates"];
Now, when updating from the perspective of bookController, things don't work quite right:
// Testing the binding from the bookController's perspective
[bookController setAnAuthor:@"Bill Gates"];
// Prints: "bookController's anAuthor: Bill Gates"
NSLog(@"bookController's anAuthor: %@", [bookController anAuthor]); // OK!
// ERROR HERE - Prints: "bookController's anAuthor: (null)"
NSLog(@"Book's author: %@", [book valueForKey:@"author"]); // DOES NOT WORK! :(
When updating from the perspective of the Book entity, things work fine:
// ------------------------------
// Testing the binding from the Book's (Entity) perspective (this works perfect)
[book setValue:@"Steve Jobs" forKey:@"author"];
// Prints: "bookController's anAuthor: Steve Jobs"
NSLog(@"bookController's anAuthor: %@", [bookController anAuthor]); // OK!
// Prints: "bookController's anAuthor: Steve Jobs"
NSLog(@"Book's author: %@", [book valueForKey:@"author"]); // OK!
It appears that the binding is partially working. I can update it on the side of the Model and it propagates up to the Controller via KVO, but if I update it on the side of the Controller, it doesn't trickle down to the Model via KVC.
Any idea on what I'm doing wrong? Thanks so much for looking! :)