Strong Typed Rows in the DataAbstract for Cocoa
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"]; |
DADataTableRow *row = self.table.rows[idx]; NSString*name = row[@"ClientName"]; |
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]; |
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 @property(strong)NSString*DepName; @property(strong)NSNumber*DepId; @property(strong)NSString*DepPhone; @end // Code for obtaining data id row = self.dataTable.rows[0]; id typedRow = row; NSNumber*depId =[typedRow DepId]; NSString*depName =[typedRow DepName]; NSString*depPhone = typedRow.DepName;// you also can use dot(.) for accessing field property NSLog(@"%@(%@): Phone:%@:", depName, depId, depPhone); |
//Protocol:@protocol DepsTableRow_Protocol @property(strong)NSString*DepName; @property(strong)NSNumber*DepId; @property(strong)NSString*DepPhone; @end // Custom row class @interface DepsTableRow : DADataTableRow // you don't need to implement DepsTableRow_Protocol for declaring its properties@end // Code for obtaining data:// First we need to register our custom row class for the particular table// It should be done once per application start // The init method of the DataAccess module is usually a good place for doing that[DADataTable registerRowClass:[DepsTableRow class] forTableName:@"Deps"]; // then later each row in the table rows array is the instance of our custom row DepsTableRow *typedRow = self.dataTable.rows[0]; NSNumber*depId =[typedRow DepId]; NSString*depName =[typedRow DepName]; NSString*depPhone = typedRow.DepName; // You can use a dot(.) to access fields as properties NSLog(@"%@(%@): Phone:%@:", depName, depId, depPhone); |
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(row); var depId := typedRow.DepId;var depName := typedRow.DepName;var depPhone := typedRow.DepPhone; NSLog("%@(%@): Phone:%@:", depName, depId, depPhone); |
// 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); |
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!