One of the most popular UI controls to represent tabular data is the NSTableView. And today I want to talk about binding RemObjects Data Abstract tables to the NSTableView.

As you might know, there are several ways to tie up data with the NSTableView.
The first one is to provide a delegate class for the NSTableView by implementing the informal NSTableViewDataSource protocol.
Another one is to use the Cocoa Bindings technology.

Let’s consider the first approach. Its advantage, from my point of view, is in its simplicity. You can manually control how the data gets into the table and from it. But you need to write the code for it and sometimes that can be boring. ;)

So let me introduce you to the DAArrayDataSource class, which will do this work (and a lot of other useful stuff) for you.

Quick start

It’s very simple to use the DAArrayDataSource. All you need to do is to create an instance of the DAArrayDataSource and set its array property and set up a proper identifier for each column of the table view in order to map the table fields to the table view columns and finally tie up the DAArrayDataSource with your NSTableView.
Take a look at the sample below:

// Create and configure the RemoteDataAdapter (I've used local Samples Server)NSURL* url =[NSURL URLWithString:@"http://192.168.0.100:8099/bin"]; DARemoteDataAdapter *adapter =[[DARemoteDataAdapter alloc] initWithTargetURL:url]; [[adapter dataService] setServiceName:@"DASampleService"];   // Get the data DADataTable *workerTable =[[adapter getDataTable:@"Workers"] retain];   //Create the DAArraySource DAArrayDataSource *arrayDS =[[DAArrayDataSource alloc] init];   // Load data here[arrayDS setArray:[workerTable rows]];   // Tie it up with the NSTableView[arrayDS setTableView:tableView];
That’s all. Simple, isn’t it?

Note:

The fact that the DAArrayDataSource encapsulates the NSTableViewDataSource methods inside will help you in case your controller has several table views. Just use separate instances of the DAArrayDataSource for each table view to avoid messiness in your code.

Sorting data

At the same time, the DAArrayDataSource provides a set of additional yummy features.
For example, without writing a line of code, you can sort data inside your table view by clicking on the column header. Moreover, you can sort by several fields at the same time. Sounds good, doesn’t it? Consider the code below:

// Sort by the Position field first[arrayDS setSortField:@"WorkerPosition"];   // Then sort by First Name[arrayDS setSecondarySortField:@"WorkerFirstName"];   // Both sorts are descending[arrayDS setSortAscending:NO];   // And that's all, from here on, the data is sorted
[![](http://blogs.remobjects.com/wp-content/uploads/2011/07/DAArrayDataSource.TwoFieldsSorting.png)](http://blogs.remobjects.com/wp-content/uploads/2011/07/DAArrayDataSource.TwoFieldsSorting.png)

Also, the DAArrayDataSource will persist the current rows selection between different modes of sorting. Just before applying sorting, it will store the selection and will try to restore it after applying new sorting. Thus you will never lose the records on which you are working at the moment.

Unfortunately, this won’t work if you try to reload all data and the entire “rows” array will be changed.

Editing & display changes

Anther interesting feature is that the DAArrayDataSource controls the ability of the table view to do inline editing.
If its read-only property equals NO, you can edit data and all changed rows will be shown in a BOLD font until they are applied, so you can easily see what changes you’ve just made.

Advanced view customization

In conclusion I think that the DAArrayDataSource is a nicely configurable class, allowing you to specify the font type, its color and size, as well as the row height for the whole NSTableView.
Using a delegate of the DAArrayDataSource, which should implement the DAArrayDataSourceDelegate, you can hook on various events. For example:

-(void)tableView:(NSTableView*)tableView needsTextColor:(NSColor**)text backgroundColor:(NSColor**)back forRow:(NSInteger)rowIndex {   // Getting the value DADataTableRow *row =[[arrayDS array] objectAtIndex:rowIndex]; NSString*positionValue =[row valueForKey:@"WorkerPosition"];   // Conditional coloringif([@"Sales Manager" compare:positionValue]== NSOrderedSame)*text =[NSColor redColor]; if([@"Sales Representative" compare:positionValue]== NSOrderedSame)*text =[NSColor greenColor]; if([@"Inside Sales Coordinator" compare:positionValue]== NSOrderedSame)*text =[NSColor blueColor]; }   -(void)tableViewSelectionDidChange:(NSTableView*)aTableView {   NSMutableString*selectedPerson =[NSMutableString stringWithString:@""]; for(DADataTableRow *row in[arrayDS selectedRows]){   [selectedPerson appendFormat:@"%@ %@ (%@)\n", [row valueForKey:@"WorkerFirstName"], [row valueForKey:@"WorkerLastName"], [row valueForKey:@"WorkerID"]]; }[selectedPersonLabel setStringValue:selectedPerson]; }
[![](http://blogs.remobjects.com/wp-content/uploads/2011/07/DAArrayDataSource.ViewCustomization.png)](http://blogs.remobjects.com/wp-content/uploads/2011/07/DAArrayDataSource.ViewCustomization.png)

That’s all, hope you enjoyed it.
If you have any questions, don’t hesitate to ask, I’ll be happy to answer.
You can get the source code of the project I’ve used above here:

In my next blog post, I’m going to write about using the Cocoa Bindings approach for binding a DADataTable to various controls.