Challenge
In DataAbstract for Cocoa, you can retrieve the values for a particular table field using the KVC approach, where the field name is passed as a string key:
| DADataTableRow *row =[[self table] rowAtIndex:idx]; NSString*name =[row valueForKey:@"ClientName"]; |
Later, with help of the new indexing syntax for arrays and dictionaries, this code can be rewritten in a more simple manner:
| DADataTableRow *row = self.table.rows[idx]; NSString*name = row[@"ClientName"]; |
But there is one flaw to that approach – the field name is passed as a string constant and thus can’t be checked in design time or selected in the code completion system. The user still has to work with *DADataTabeRow* instances, where data is represented by the dictionary, rather than by business objects.
Solution
With the help of some “Magic” in Objective-C, we can now offer another approach for getting values for a particular column in a row.
You can just operate with a particular field in the table row as with a usual property.
This means that you can call any property in a row instance like this:
| id fieldValue =[self.dataTable.rows[idx] MyFieldName]; |
If there is no such field in the table, you will get a proper exception, otherwise you will get its value.
It would also be great though if we could choose available fields using the Code Completion system inside the IDE.
This would simplify the code and allow to avoid various possible mistakes in specifying field names when working with data of the row.
And the answer is yes, we can do that.
All we need to do is to represent the available table fields as properties of a special protocol (interface) that the row can support.
This approach can be used in two ways:
The most simple way is to just generate protocols ad later cast the row instance to the row protocol. For example:
| // Protocol @protocol DepsTableRow_Protocol |
Another approach is to provide a special row class for the particular table. This class must be inherited from the base *DADataTableRow* class, but in addition, it can expose different properties:
| //Protocol:@protocol DepsTableRow_Protocol |
## Supporting Strong Typed Rows in Nougat
The same approaches are also available for Nougat projects and Oxygene:
| // Protocol DepsTableRow_Protocol=publicinterfaceproperty DepName: strong NSString readwrite;property DepId: strong NSNumber readwrite;property DepPhone: strong NSString readwrite;end; // Code for obtaining data var row: id :=self.dataTable.rows[0];var typedRow : DepsTableRow_Protocol := duck |
and for RemObjects C# (Hydrogene):
| // Protocolpublicinterface DepsTableRow_Protocol { __strong NSString DepName {get;set;} __strong NSNumber DepId {get;set;} __strong NSString DepPhone {get;set;}} // Code for obtaining data id row = self.dataTable.rows[0]; DepsTableRow_Protocol typedRow = duck<DepsTableRow_Protocol>(row); NSNumber depId = typedRow.DepId; NSString depName = typedRow.DepName; NSString depPhone = typedRow.DepPhone; NSLog("%@(%@): Phone:%@:", depName, depId, depPhone); |
## Generating protocols
The one remaining question is how to get those row protocols?
For Nougat projects created in MS Visual Studio, these protocols will be generated automatically by the New Project Wizard.
You can also update/regenerate these protocols any time you want – just run the wizard by clicking Create Table Definition Classes in the Solution Explorer window.

For Xcode projects, you can generate the protocols directly from the schema node inside the Relativity Server in the Server Explorer for Cocoa tool. It allows to generate Objective-C, Oxygene and RemObjects C# protocols for Nougat projects.

Samples
Take a look at the StrongTypedRows (iOS) samples written in Nougat, Oxygene and RemObjects C#. We are providing them with the DataAbstract for Cocoa package.
Thanks for reading!