TestsTested | ✓ |
LangLanguage | Obj-CObjective C |
License | Custom |
ReleasedLast Release | Sep 2016 |
Maintained 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.
Use CocoaPods, or Set up manually
Source/FusionTablesAPI
and Source/GoogeService
folders to your project's target.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:
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>]
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.
In the sample project's directory, run:
$ pod install
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.
FTTable
class is the Objective-C representation of the Fusion Table resource, with corresponding methods such as list....
, insert....
, update....
, delete....
.FTTemplate
and FTStyle
classesFTSQLQuery
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.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"]);
}
}
}];
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);
}
}];
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.
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");
}
}
}];
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");
}
}
}];
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 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.
Obj-C-FusionTables requires ARC and are optimized for iOS8 and above.