Data Paging using the Windows Azure Mobile Services iOS client SDK

As another follow up to an earlier post, I'm walking through the Windows Azure Mobile Services Tutorials to add in the iOS client version of handling data validation. This tutorial (like the earlier one), will appear on windowsazure.com soon, builds up from either the Getting Started With Data or the Using Scripts to Authorize Users iOS tutorials, in that you can use a running application and service from either of those tutorials to get service validation working and handled properly on the client. Then we'll walk through data paging and continue on the tour.

The steps are as follows. You must have either the Getting Started With Data or the Using Scripts to Authorize Users iOS tutorials completed and running.

  1. Open the project of one of the preceding iOS tutorial applications.
  2. Run the application, and enter at least four (4) items.
  3. Open the TodoService.m file, and locate the - (void) refreshDataOnSuccess:(CompletionBlock)completion method. Replace the body of the entire method with the following code. This query returns the top three items that are not marked as completed. (Note: To perform more interesting queries, you use the MSQuery instance directly.)

    // Create a predicate that finds active items in which complete is false
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"complete == NO"];
    
    // Retrieve the MSTable's MSQuery instance with the predicate you just created.
    MSQuery * query = [self.table queryWhere:predicate];
        
    query.includeTotalCount = TRUE; // Request the total item count
    
    // Start with the first item, and retrieve only three items
    query.fetchOffset = 0;
    query.fetchLimit = 3;

    // Invoke the MSQuery instance directly, rather than using the MSTable helper methods.
    [query readWithCompletion:^(NSArray *results, NSInteger totalCount, NSError *error) {
        
        [self logErrorIfNotNil:error];
           if (!error)
        {
            // Log total count.
            NSLog(@"Total item count: %@",[NSString stringWithFormat:@"%zd", (ssize_t) totalCount]);
            
           }
        
        items = [results mutableCopy];
        
        // Let the caller know that we finished
        completion();
    }];

4. Press Command + R to run the application in the iPhone or iPad simulator. You should see only the first three results listed in the application.

5. (Optional) View the URI of the request sent to the mobile service by using message inspection software, such as browser developer tools or a Mac OSX Fiddler equivalent like the Burp Suite, Charles Proxy, or HTTP Scoop. (I note that even iOS devs that do a lot of cross platform work use fiddler.) Notice that the fetchLimit = 3 property assignment was translated into the query option $top=3 in the query URI.

6. Update the RefreshTodoItems method once more by locating the query.fetchOffset = 0; line and setting the query.fetchOffset value to 3. This will take the next three items after the first three.

These modified query properties:

    query.includeTotalCount = TRUE; // Request the total item count  

    // Start with the fourth item, and retrieve only three items

    query.fetchOffset = 3;

    query.fetchLimit = 3;

skips the first three results and returns the next three after that (in addition to returning the total number of items available for your use). This is effectively the second "page" of data, where the page size is three items.

7. (Optional) Again view the URI of the request sent to the mobile service. Notice that the query.fetchOffset value was translated into the query option $skip=3 in the query URI.

8. Finally, if you want to note the total number of possible Todo items that can be returned, we wrote that to the output window in Xcode. Mine looked like this:

2012-10-28 00:02:34.182 Quickstart[1863:11303] Total item count: 8

but my application looked like this:

With that, and the total count, and you can implement any paging you might like, including infinite lazy scrolling.

-- Ralph