Obj-C-FusionTables 2.0.4

Obj-C-FusionTables 2.0.4

TestsTested
LangLanguage Obj-CObjective C
License Custom
ReleasedLast Release Sep 2016

Maintained by Arseniy Kuznetsov.




  • By
  • Arseniy Kuznetsov

Google Fusion Tables is a powerful combination of a big web store and variety of ways to access and visualize the data. While still marked as 'experimental', it has reached its maturity with Fusion Tables API v2.0 and offers developers clean & easy ways to enrich their apps across variety of development platforms.

One potential obstacle for using Fusion Tables in iOS apps is that there is no official, dedicated Objective-C API.

Obj-C-FusionTables is an easy and ready-to-use solution for integrating Fusion Tables into iOS apps, built entirely on top of the Google gtm-oauth2 and gtm-http-fetcher libraries.

Blog

Obj-C-FusionTables

Installation

Use CocoaPods, or Set up manually

Manual

  • Add all files from the Source/FusionTablesAPI and Source/GoogeService folders to your project's target.
  • Install Google gtm-oauth2 library

Setting up your Google Project

To communicate with Fusion Tables and other Google services, you need an OAuth 2.0 client ID that your application will use when requesting an OAuth 2.0 access token.

The OAuth 2.0 client ID for your project can be set up in the Google Developers Console as described in details here.

In the Google API sections of your project, enable the APIs as shown below:

api

Now back in your Xcode project, put this line of code at appropriate place such as in the App's Delegate application:didFinishLaunchingWithOptions: method:

[[GoogleAuthorizationController sharedInstance] registerClientID:<YOUR-OAUTH2-CLIENT_ID>]

Sample Project

The sample project is an universal iOS8 app that runs in both iPhone and iPad simulators. Its main purpose is to show typical usage of Obj-C-FusionTables for common Fusion Tables operations such as listing tables, creating a table, setting Map styles, adding InfoWindow templates, executing SQL queries, inserting and deleting rows, sharing your fusion tables, etc.

If you already have Fusion Tables in your Google account, they will show up in the sample app. To ensure safety of your data, only the tables created from within the sample app can be modified.

Installing pods

In the sample project's directory, run:

$ pod install

Googe Project Setup

To run the sample project, you need to follow to the above instructions on setting up your Google project and filling in your own Google API key in the App's Delegate application:didFinishLaunchingWithOptions: method.

Usage

  • Install Obj-C-FusionTables as described above
  • Take a quick look at the Obj-C-FusionTables classes to familiarize yourself with the concepts. If you already have some level of experience with Google Fusion Tables API v2.0, things should be mostly self-explanatory.
  • FTTable class is the Objective-C representation of the Fusion Table resource, with corresponding methods such as list...., insert...., update...., delete.....
  • The same applies to other Fusion Tables resources such as Templates and Styles, represented by the FTTemplate and FTStyle classes
  • FTSQLQuery class represents the Fusion Table SQL query resource and has corresponding methods such as select..., insert..., update..., delete....
  • FTSQLQueryBuilder helps build SQL statements for various SQL queries.
  • GoogleAuthorizationController class conveniently wraps around Google Authentication library, providing simple ways to sign-in / sign-out and authenticating general requests to Google Services.
  • GoogleServicesHelper provides an easy & light-weight access to related Google services such as URL Shortener or Google Drive ACL. While libraries such as Google APIs Client already cover these in greater depth, they would also require non-trivial installation & would introduce yet another set of APIs.

A few quick code samples

  • read a list of Fusion Tables
FTTable *ftTable = [[FTTable alloc] init];
ftTable.ftTableDelegate = self;
[ftTable listFusionTablesWithCompletionHandler:^(NSData *data, NSError *error) {
    if (error) {
        NSString *errorStr = [SimpleGoogleServiceHelpers remoteErrorDataString:error];
        NSLog(@"Error Listing Fusion Tables: %@", errorStr);
    } else {
        NSDictionary *ftItems = [NSJSONSerialization JSONObjectWithData:data
                                                                  options:kNilOptions error:nil];
      NSArray *ftTableObjects = [NSMutableArray arrayWithArray:ftItems[@"items"]];
      for (NSDictionary *ftTable in ftTableObjects) {
            NSLog(@"Table Name: %@", ftTable[@"name"]);
            NSLog(@"Table ID: %@", ftTable[@"tableId"]);
        }
    }
}];
  • insert a new Fusion Table
FTTable *ftTable = [[FTTable alloc] init];
ftTable.ftTableDelegate = self;
[ftTable insertFusionTableWithCompletionHandler:^(NSData *data, NSError *error) {
    if (error) {
      NSString *errorStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
          NSLog(@"Error Inserting Fusion Table: %@", errorStr);
    } else {
      NSDictionary *contentDict = [NSJSONSerialization JSONObjectWithData:data
                                                                    options:kNilOptions error:nil];
          NSLog(@"Inserted a new Fusion Table: %@", contentDict);
    }
}];
  • delete a Fusion Table
FTTable *ftTable = [[FTTable alloc] init];
ftTable.ftTableDelegate = self;
[ftTable deleteFusionTableWithCompletionHandler:^(NSData *data, NSError *error) {
    [[SimpleGoogleServiceHelpers sharedInstance] decrementNetworkActivityIndicator];
    if (error) {
        NSString *errorStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"Error Deleting Fusion Table: %@", errorStr);
    }
}];

Similar coding patterns work for Fusion Tables Templates and Styles.

  • Insert Fusion Table rows
FTSQLQuery *ftSQLQuery = [[FTSQLQuery alloc] init];
ftSQLQuery.ftSQLQueryDelegate = self;
[ftSQLQuery sqlInsertWithCompletionHandler:^(NSData *data, NSError *error) {
    if (error) {
        NSString *errorStr = [GoogleServicesHelper remoteErrorDataString:error];
        NSLog (@"Error Inserting Fusion Table Style: %@", errorStr);
    } else {
        NSDictionary *responceDict = [NSJSONSerialization
                                      JSONObjectWithData:data options:kNilOptions error:nil];
        NSArray *rows = responceDict[@"rows"];
        if (rows) {
            NSLog(@"Inserted %d %@", [rows count], ([rows count] == 1) ? @"row" : @"rows");
            NSLog(@"%@", rows);
            NSUInteger lastInsertedRowID = [(NSString *)((NSArray *)[rows lastObject])[0] intValue];
        } else {
            NSLog (@"Error processing Insert Rows response");
        }
    }
}];
  • Delete Fusion Table rows
FTSQLQuery *ftSQLQuery = [[FTSQLQuery alloc] init];
ftSQLQuery.ftSQLQueryDelegate = self;
[ftSQLQuery sqlDeleteWithCompletionHandler:^(NSData *data, NSError *error) {
    if (error) {
        NSString *errorStr = [GoogleServicesHelper remoteErrorDataString:error];
        STFail (@"Error Inserting Fusion Table Style: %@", errorStr);
    } else {
        NSDictionary *responceDict = [NSJSONSerialization
                                      JSONObjectWithData:data options:kNilOptions error:nil];
        NSArray *rows = responceDict[@"rows"];
        if (rows) {
            NSUInteger numRowsDeleted = [(NSString *)((NSArray *)[rows lastObject])[0] intValue];
            NSLog(@"Deleted %d %@", numRowsDeleted, (numRowsDeleted == 1) ? @"row" : @"rows");
        } else {
            NSLog (@"Error processing Delete Rows response");
        }
    }
}];

The Delegates

After a brief glance on e.g. the Delete Table code above, a first quick question might be "so where the heck is the table ID coming from?" Since FTTable class is a representation of a stateless web resource, a logical way of handling parametrization is via the delegation pattern. The FTTable delegate is defined as follows:

@protocol FTDelegate <NSObject>
@optional
- (NSString *)ftTableID;
- (NSArray *)ftColumns;
- (NSString *)ftTitle;
- (NSString *)ftDescription;
- (BOOL)ftIsExportable;
@end

This way things are more flexible, letting you implement the delegate where it makes sense in your app rather than going into parameterizing / subclassing the FTTable class. A similar approach is used for other Obj-C-FusionTables core classes such as FTStyle and FTTemplate.

FTSQLQuery delegate is slightly different though essentially follows the same design pattern:

@protocol FTSQLQueryDelegate <NSObject>
@optional
- (NSString *)ftSQLSelectStatement;
- (NSString *)ftSQLInsertStatement;
- (NSString *)ftSQLUpdateStatement;
- (NSString *)ftSQLDeleteStatement;
@end

A simple way to learn more about implementing specific delegates is via looking at the sample project. While obviously it requires some level of the Fusion Tables API knowledge, the Objective-C part of it as quite straightforward. A quick code sample:

// Sample Fusion Table Title
- (NSString *)ftTitle {
    return @"My new cool table";
}
// Sample Fusion Table Columns Definition
- (NSArray *)ftColumns {
    return @[
     @{@"name": @"entryDate",
       @"type": @"STRING"
       },
     @{@"name": @"entryName",
       @"type": @"STRING"
       },
     @{@"name": @"geometry",
       @"type": @"LOCATION"
       }];
}

Another way to learn the API is of course via taking a look at the Obj-C-FusionTablesTests (see below).

The Tests

The tests are intended to cover all essential Obj-C-FusionTables API operations. The test cases go from creating a table / style / template / inserting sample rows through cleaning everything up and restoring the tested Google account to its initial state.

Compatibility

Obj-C-FusionTables requires ARC and are optimized for iOS8 and above.