Search code examples
objective-ccocoacore-datacocoa-bindings

Bind an NSArray with NSArrayController and display the results in NSTableView


I work on trivial core data, non document based cocoa app. There are 3 entities in my core data, and they have one to one relationship.

Entities can be seen on the image bellow:enter image description here

I can manage to display the values in the console log, but I can't display them in the NSTableView.

Here is my code:

.h file:

#import <Cocoa/Cocoa.h>
#import "AppDelegate.h"

@interface CombinedViewController : NSViewController <NSTableViewDataSource>

    @property (nonatomic,strong) NSManagedObjectContext *mObjContext;
    @property AppDelegate *appDelegate;
    @property (strong) IBOutlet NSArrayController *combinedRecordsArrayController;
    @property (nonatomic,strong)NSArray *websites;
    @property (weak) IBOutlet NSTableView *combinedTableView;
    @property(strong,nonatomic)NSString *hostingProvider;
    @property(strong,nonatomic)NSString *customerName;
    @property(strong,nonatomic)NSString *websiteUrl;

@end

.m file

#import "CombinedViewController.h"
#import "Website.h"
#import "Customer.h"
#import "Hosting.h"

@interface CombinedViewController ()

@end

@implementation CombinedViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
        _appDelegate = (AppDelegate*)[[NSApplication sharedApplication] delegate];
        self.mObjContext = _appDelegate.managedObjectContext;
    }

    -(void)viewDidAppear {
        [self getCombinedResutls];
    }

    -(NSArray *)getCombinedResutls {
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Website" inManagedObjectContext:self.mObjContext];
        [fetchRequest setEntity:entity];
        NSError *error = nil;
        NSArray *fetchedObjects = [self.mObjContext executeFetchRequest:fetchRequest error:&error];
        if (fetchedObjects == nil) {
            NSLog(@"Error:%@",error);
        }
        self.websites = [self.mObjContext executeFetchRequest:fetchRequest error:nil];
            for (Website *ws in self.websites) {
                self.hostingProvider = ws.hostingInfo.hostingProvider;
                self.customerName = ws.customerInfo.customerName;
                NSLog(@"Website: %@, Customer: %@, Hosting Provider: %@", ws.websiteUrl, self.customerName, self.hostingProvider);
            }

        return self.websites;
    }

@end

I have an NSArrayController, named CombinedRecordsArrayController, which in attributes contoller has the following: Mode = Class, ClassName = CombinedViewContoller and both checkboxes are checked, those are Prepares Content and Editable. In binding, I have set the manage object context to file ownder, Model Key Path self.mObjContext.

NSTable is binded with this NSArrayContoller, and if I left only the first column, that is websiteUrl, I get the results.

NSLog line in my .m file, do print the results. However app crash with following error:

[ valueForUndefinedKey:]: the entity Website is not key value coding-compliant for the key "hostingProvider". Any help will be deeply appreciated. I am struggling with this 4-5 days, and I can't solve it.


Solution

  • Core Data, NSArrayController and NSTableView is easy, if you know how to do it.

    Array Controller:
    Set Mode to Entity Name.
    Set Entity Name to the name of the entity.
    Check Prepares Content and Editable.
    Bind Managed Object Context to the managed object context.

    Table View:
    Bind Content to the array controller, Controller Key arrangedObjects.
    Bind Selection Indexes to the array controller, Controller Key selectionIndexes.
    Bind Sort Descriptors to the array controller, Controller Key sortDescriptors.
    Bind Value of the table view cell to Table Cell View, Model Key Path objectValue.websiteUrl. Check Conditionally Sets Editable.

    That's it.