After several hours/days of searching and diving into example projects I've concluded that I need to just ask. If I bind the assetsView (IKImageBrowserView
) directly to an IB instance of NSArrayController
everything works just fine.
- (void) awakeFromNib
{
library = [[NSArrayController alloc] init];
[library setManagedObjectContext:[[NSApp delegate] managedObjectContext]];
[library setEntityName:@"Asset"];
NSLog(@"%@", [library arrangedObjects]);
NSLog(@"%@", [library content]);
[assetsView setDataSource:library];
[assetsView reloadData];
}
Both NSLogs
are empty. I know I'm missing something... I just don't know what. The goal is to eventually allow multiple instances of this view's "library" filtered programmatically with a predicate. For now I'm just trying to have it display all of the rows for the "Asset" entity.
Addition: If I create the NSArrayController
in IB and then try to log [library arrangedObjects]
or manually set the data source for assetsView I get the same empty results. Like I said earlier, if I bind library.arrangedObjects
to assetsView.content
(IKImageBrowserView
) in IB - with same managed object context and same entity name set by IB - everything works as expected.
- (void) awakeFromNib
{
// library = [[NSArrayController alloc] init];
// [library setManagedObjectContext:[[NSApp delegate] managedObjectContext]];
// [library setEntityName:@"Asset"];
NSLog(@"%@", [library arrangedObjects]);
NSLog(@"%@", [library content]);
[assetsView setDataSource:library];
[assetsView reloadData];
}
It looks like the problem is that you have not actually told the NSArrayController to fetch anything. NSArrayControllers are empty until you add objects either through bindings or manually.
After setting up library try to call its fetch method:
[library fetch:self];
Also, you probably know this already but it is possible to set bindings in code with the following method:
- (void)bind:(NSString *)binding toObject:(id)observableController withKeyPath:(NSString *)keyPath options:(NSDictionary *)options
I was running into a similar situation where the (IKImageBrowserView) was not initializing even though the ArrayController would ultimately sync up with the NSManagedObjectContext.
Ultimately found this passage in the core data programming guide
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdBindings.html#//apple_ref/doc/uid/TP40004194-SW3
if the "automatically prepares content" flag (see, for example,
setAutomaticallyPreparesContent:) is set for a controller, the controller's initial content
is fetched from its managed object context using the controller's current fetch predicate. It
is important to note that the controller's fetch is executed as a delayed operation performed
after its managed object context is set (by nib loading)—this therefore happens after
awakeFromNib and windowControllerDidLoadNib:. This can create a problem if you want to
perform an operation with the contents of an object controller in either of these methods,
since the controller's content is nil. You can work around this by executing the fetch
"manually" with fetchWithRequest:merge:error:.
- (void)windowControllerDidLoadNib:(NSWindowController *) windowController
{
[super windowControllerDidLoadNib:windowController];
NSError *error = nil;
BOOL ok = [arrayController fetchWithRequest:nil merge:NO error:&error];
// ...
Can also be added in awakeFromNib if subclassing the NSArrayCotroller or via your view controller
-(void)awakeFromNib
{
[self fetchWithRequest:nil merge:NO error:nil];
...
}