Asynchronous Calls

The AsynchronousCalls is a console based sample that demonstrates different ways to asynchronously use getDataTable: method to retrieve a table from the server. Note that while this sample demonstrates using the beginGetDataTable:select:where:withBlock: & beginGetDataTable:select:where:start: asynchronous methods of DARemoteDataAdapter, there are a number of other variants available.

Getting Started

The Console sample is typically located in /Developer/RemObjects Software/Samples/Data Abstract/Console/AsynchronousCalls, though you may have installed the Data Abstract for Cocoa and it's samples in another location.

To build it, you will of course need Xcode, and like all the samples provided with Data Abstract for Cocoa you will need to be running the Relativity Server with the DASamples Domain and the Simple Schema available.

Lastly this sample makes use of a convenience method (DALogTable) provided by a class extension to NSArray that we ship with Data Abstract for Cocoa. It is actually a #define method that uses one of three new log methods added to NSArray to print the contents of a DADataTable in a pretty fashion to the console using NSLog. To use this in your own code you must add the following to your import statements #import <DataAbstract/NSArray+DADataTableLog.h>. Please note that this class extension is intended for test purposes only.

Running the Sample

The sample when run establishes a connection to an instance of Relativity Server, and then steps through three different ways of using getDataTable: in an asynchronous fashion to retrieve the Clients table, with the ClientId, ClientName and ClientPhone fields selected and print the returned table to the console.

The first uses Grand Central Dispatch to execute the getDataTable:select:where: method in a background queue and then print the table to the console on the main queue when the method returns (Step 1).

The second uses the asynchronous method beginGetDataTable:select:where:withBlock: which takes a block argument to be called when the method is complete (Step 2).

Lastly the sample uses the asynchronous method beginGetDataTable:select:where:start: which requires a delegate that will be called when the method is complete. (Step 3).

Examining the Code

The code for creating the connection to the server and handling logging in is covered by other samples. In this section we shall focus solely on the calls for getDataTable:select:where: and beginGetDataTable:select:where:start: used in Steps 1-3 method of DARemoteDataAdapter.

The code for this sample is split into two files, main.m which creates a DataAccess object, and executes each of the asynchronous requests before executing a while loop that will keep going until the busy property of DataAccess is false; this is simply to prevent the sample from finishing before the asynchronous calls have been completed. The DataAccess class handles establishing the connection to an instance of Relativity Server in the init method, the async calls to the server and finally there is an defined getter method for the busy property that returns a BOOL based on the state of GCDCallDone, DABlockCallDone and DADelegateCallDone boolean variables.

NOTE that passing an incorrect table name, or field name, to the getDataTable methods will cause an ROException to be throw which should be handled appropriately.

Using getDataTable:select:where: (Steps 1)

The step uses Grand Central Dispatch (GCD) to execute the synchronous method getDataTable:select:where: in a background queue before then executing DALogTable to print the results to the console on the main queue (where you must normally do an UI updates). The array being passed to select: is a list of the fields that we are want to have returned from the Clients table; this is using the Dynamic Select feature of Data Abstract.

It is generally recommended to use the begin* methods to execute asynchronous requests rather than wrapping the synchronous methods in GCD yourself unless you have a particular reason not to.

- (void)asyncCall_GCD {

    NSLog(@"GCD: Begin loading Clients data");
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        DADataTable * t = [self.dataAdapter getDataTable:@"Clients" select:@[@"ClientId", @"ClientName", @"ClientPhone"] where:nil];
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"GCD: Clients data has been retrieved.");
            DALogTable(t);
            GCDCallDone = YES;
        });
    });
}

Using beginGetDataTable:select:where:withBlock: (Step 2)

This is the first of two asynchronous variants of getDataTable:select:where:. The beginGetDataTable:select:where:withBlock: method executes immediately when called, and an additional argument which is the block to execute when the call is completed.

- (void)asyncCall_DA_Block {

    NSLog(@"DA+Block: Begin loading Clients data");
    [self.dataAdapter beginGetDataTable:@"Clients"
                                 select:@[@"ClientId", @"ClientName", @"ClientPhone"]
                                  where:nil
                              withBlock:^(DADataTable * t) {
        NSLog(@"DA+Block: Clients data has been retrieved.");
        DALogTable(t);
        DABlockCallDone = YES;
    }];
}

Using beginGetDataTable:select:where:start: (Step 3)

This variant of getDataTable:select:where: can be set up at any time, but have the execution delayed until a future point in time if you desire. The beginGetDataTable:select:where:start: method returns a DAAsyncRequest object which represents the asynchronous request, in this case because NO is passed to start: the request is currently not being executed.

The DAAsyncRequest can be used to check the status of the request, to assign a class that implements DAAsyncRequestDelegate protocol as a delegate or to execute the request if NO had been passed as the start: argument.

Here we as store the returned DAAsyncRequest object to asyncRequest and then assign the DataAccess class as the delegate as it implements the asyncRequest:didReceiveTable: method, which will print out the table when the call is completed. We then use the start method to begin the asynchronous request and once the request is complete, it calls the delegate method which prints the table to the console.

- (void)asyncCall_DA_AsyncRequestDelegate {

    NSLog(@"DA+AsyncRequestDelegate: Begin loading Clients data");
    DAAsyncRequest * asyncRequest =
        [self.dataAdapter beginGetDataTable:@"Clients"
                                     select:@[@"ClientId", @"ClientName", @"ClientPhone"]
                                      where:nil
                                      start:NO];
    asyncRequest.delegate = self;
    [asyncRequest start];
}

- (void)asyncRequest:(DAAsyncRequest *)request didReceiveTable:(DADataTable *)table {
    NSLog(@"DA+AsyncRequestDelegate: Clients data has been retrieved.");
    DALogTable(table);
    DADelegateCallDone = YES;
}

Example Output

This is an example of the output you will see when the sample is run.

Transport layer is configured.
DataAdapter is configured.
Trying to login with login string User=simple;Password=simple;Domain=DASamples;Schema=Simple...
Login successful
-------------------------------------------------------------------------------------------------------
STEP 1: Calling GetData method asynchronously using GrandCentralDispatch way...
GCD: Begin loading Clients data
-------------------------------------------------------------------------------------------------------
STEP 2: Calling GetData method asynchronously using DataAbstract approach with block...
DA+Block: Begin loading Clients data
-------------------------------------------------------------------------------------------------------
STEP 3: Calling GetData method asynchronously using DataAbstract approach with AsyncRequest delegate...
DA+AsyncRequestDelegate: Begin loading Clients data
-------------------------------------------------------------------------------------------------------
Waiting for async call completion
DA+Block: Clients data has been retrieved.
TABLE: Clients (24 rows from 24)
-----------------------------------------------------------
| ClientId| ClientName            | ClientPhone           |
-----------------------------------------------------------
| 1       | Mollie Bennett (edited| (171) 555-1212        |
| 2       | Gale Dalton           | 0221-0644327          |
| 3       | Matthew Decker        | (503) 555-3612        |
| 4       | Joseph Henson234      | (939)399-99-99        |
| 5       | Jennifer Kent         | (11) 555-7647         |
| 6       | Sandy Manning         | (1) 354-2534          |
| 7       | Glenn Cunningham      | 0522-556721           |
| 8       | Marcy Collins         | (14) 555-8122         |
| 9       | Kirsten Rosario       | (930)930-30-93        |
| 10      | Merle Frank           | (415) 555-5938        |
| 11      | Will Smith            | (714) 256-0552        |
| 12      | John Doe              | (612) 276-0136        |
| 13      | Ian G. Kim            | (612) 276-0136        |
| 14      | Jermaine M. Miller    | (814) 343-0945        |
| 15      | Jean C. Gates         | (757) 382-4391        |
| 16      | David M. Lee          | (704) 718-1664        |
| 17      | Jennifer K. Jones     | (859) 491-4222        |
| 18      | Brian L. Rowles       | (908) 385-7809        |
| 19      | Angela W. Vanover     | (610) 463-9999        |
| 20      | Anna H. Kugler        | (817) 249-9525        |
| 21      | Randy R. Howard       | (234) 567-8909        |
| 22      | Kenny S. Lay          | (817) 249-9525        |
| 23      | Maryann C. Bachmann   | (907) 722-6777        |
| 24      | Lillie R. Schroeder   | (312) 476-1404        |
-----------------------------------------------------------
GCD: Clients data has been retrieved.
TABLE: Clients (24 rows from 24)
-----------------------------------------------------------
| ClientId| ClientName            | ClientPhone           |
-----------------------------------------------------------
| 1       | Mollie Bennett (edited| (171) 555-1212        |
| 2       | Gale Dalton           | 0221-0644327          |
| 3       | Matthew Decker        | (503) 555-3612        |
| 4       | Joseph Henson234      | (939)399-99-99        |
| 5       | Jennifer Kent         | (11) 555-7647         |
| 6       | Sandy Manning         | (1) 354-2534          |
| 7       | Glenn Cunningham      | 0522-556721           |
| 8       | Marcy Collins         | (14) 555-8122         |
| 9       | Kirsten Rosario       | (930)930-30-93        |
| 10      | Merle Frank           | (415) 555-5938        |
| 11      | Will Smith            | (714) 256-0552        |
| 12      | John Doe              | (612) 276-0136        |
| 13      | Ian G. Kim            | (612) 276-0136        |
| 14      | Jermaine M. Miller    | (814) 343-0945        |
| 15      | Jean C. Gates         | (757) 382-4391        |
| 16      | David M. Lee          | (704) 718-1664        |
| 17      | Jennifer K. Jones     | (859) 491-4222        |
| 18      | Brian L. Rowles       | (908) 385-7809        |
| 19      | Angela W. Vanover     | (610) 463-9999        |
| 20      | Anna H. Kugler        | (817) 249-9525        |
| 21      | Randy R. Howard       | (234) 567-8909        |
| 22      | Kenny S. Lay          | (817) 249-9525        |
| 23      | Maryann C. Bachmann   | (907) 722-6777        |
| 24      | Lillie R. Schroeder   | (312) 476-1404        |
-----------------------------------------------------------
DA+AsyncRequestDelegate: Clients data has been retrieved.
TABLE: Clients (24 rows from 24)
-----------------------------------------------------------
| ClientId| ClientName            | ClientPhone           |
-----------------------------------------------------------
| 1       | Mollie Bennett (edited| (171) 555-1212        |
| 2       | Gale Dalton           | 0221-0644327          |
| 3       | Matthew Decker        | (503) 555-3612        |
| 4       | Joseph Henson234      | (939)399-99-99        |
| 5       | Jennifer Kent         | (11) 555-7647         |
| 6       | Sandy Manning         | (1) 354-2534          |
| 7       | Glenn Cunningham      | 0522-556721           |
| 8       | Marcy Collins         | (14) 555-8122         |
| 9       | Kirsten Rosario       | (930)930-30-93        |
| 10      | Merle Frank           | (415) 555-5938        |
| 11      | Will Smith            | (714) 256-0552        |
| 12      | John Doe              | (612) 276-0136        |
| 13      | Ian G. Kim            | (612) 276-0136        |
| 14      | Jermaine M. Miller    | (814) 343-0945        |
| 15      | Jean C. Gates         | (757) 382-4391        |
| 16      | David M. Lee          | (704) 718-1664        |
| 17      | Jennifer K. Jones     | (859) 491-4222        |
| 18      | Brian L. Rowles       | (908) 385-7809        |
| 19      | Angela W. Vanover     | (610) 463-9999        |
| 20      | Anna H. Kugler        | (817) 249-9525        |
| 21      | Randy R. Howard       | (234) 567-8909        |
| 22      | Kenny S. Lay          | (817) 249-9525        |
| 23      | Maryann C. Bachmann   | (907) 722-6777        |
| 24      | Lillie R. Schroeder   | (312) 476-1404        |
-----------------------------------------------------------
[Done]
Program ended with exit code: 0

NOTE: For clarity the date and process name and ID have been removed from the sample text above