Using Endpoints in an iOS Client
To use Endpoints in an iOS app, you need to:
- Have access to the backend API project that the client is going to access.
- Have a system running Mac OSX and Xcode.
- Compile the client library generator and generate your library .
- Add required files to your iOS project.
- Create the service object to be used for making requests.
- Call the API exposed by the Endpoint.
- Optionally, add support for authenticated calls .
Compiling the client library generator and generating your library
To compile the library generator and then use it to generate your client library:
-
On the system where you have your backend API project, generate the discovery document from your backend API in RPC format following the instructions provided in Generating a Discovery Doc .
-
On a system running a recent version of Mac OSX that has the Xcode development environment installed, check out a read-only copy of the Google APIs Client Library as follows:
svn checkout \ http://google-api-objectivec-client.googlecode.com/svn/trunk/ \ google-api-objectivec-client-read-only
The Google APIs Client Library for Objective-C project contains all of the code for the Objective-C client library as well as the client library generator.
-
Start Xcode, and in the above download of the Google APIs Client source, locate
google-api-objectivec-client-read-only/Source/Tools/ServiceGenerator/ServiceGenerator.xcodeproj
. This project contains a single target,ServiceGenerator
. Build this target ( Project->Build or ⌘B) . -
After you build that target, in the Xcode Project Navigator , expand the
ServiceGenerator
project andProducts
arrows to display the output binary. Click on the binary and get the full path from the File Inspector. -
Open a new Terminal window and invoke
ServiceGenerator
, pasting in the path to theServiceGenerator
binary. As arguments, include the path to your discovery document in RPC format that you created previously. Use the following invocation:/Users/foo/Library/Developer/Xcode/DerivedData/ServiceGenerator-abc/Build/Products/Debug/ServiceGenerator \ ~/src/tictactoe-java/war/WEB-INF/tictactoe-v1-rpc.discovery \ --outputDir ~/API
replacing the paths and application name with those for your own project.
-
After you successfully complete these procedures, you now have an API directory containing all of the supplementary files you’ll need to access your API (on top of the existing client library). We'll show you how to add these files to your project in the next section.
Adding required files to your iOS project
To add the required files:
-
If you are
not
using the Google+ iOS SDK, add the client library to your iOS project in Xcode. (If you
are
using
the Google+ iOS SDK, you must skip this step.) There are two ways to add the client library:
-
The first way is to copy the source files for the library into your project and compile them directly. To do this,
-
Open
google-api-objectivec-client-read-only/Source/GTL.xcodeproj
and expand GTLSource and Common. - Select all the files in the subgroups, excluding the OAuth 2.0/Mac group.
- Drag the selected files into the Project Navigator of your own open project. (You may wish to put them into their own group for organizational purposes, but that is not required.)
- Select your project in the Add to targets selection area.
- If your project uses Automatic Reference Counting (ARC), disable it for the client library files you include.
- Under the target Build Phases tab for your project, and expand the Compile Sources build phase.
-
Select the library source files, then press Enter to open the edit field., and type
-fno-objc-arc
as the compiler flag for those files.
-
Open
-
The second way to add the client library is to compile and link to the static iOS framework, and is described in the
objectivec client
documentation.
-
The first way is to copy the source files for the library into your project and compile them directly. To do this,
-
If you are using the Google+ iOS SDK, set up your Xcode project as follows:
- In your Xcode project, go to the settings page for the target.
-
In the
Build Settings
tab, add the following item to
Header Search Paths
:
<GOOGLE_PLUS_SDK_DIRECTORY>/GoogleOpenSource.framework/Headers
where<GOOGLE_PLUS_SDK_DIRECTORY>
is the directory where you installed the Google+ iOS SDK.
-
Add the output of
ServiceGenerator
you generated previously. Just drag these files from the Finder into the Project Navigator for your project, making sure you omit all files containing_Sources
. (If you don't omit the_Sources
files, you may get symbol conflicts during compilation.) You may wish to put the files into their own group. Disabling ARC is not required for these files.
Creating the service object
The service object is required for making requests to the Endpoint API. If your app makes unauthenticated requests, you construct a service object as follows:
static GTLServiceTictactoe *service = nil;
if (!service) {
service = [[GTLServiceTictactoe alloc] init];
service.retryEnabled = YES;
[GTMHTTPFetcher setLoggingEnabled:YES];
}
For authenticated calls, you'll need to supply credentials to the service object .
Calling the Endpoint API (unauthenticated)
After you create a service object, calling your API is straightforward, as shown by this example:
GTLQueryTictactoe *query = [GTLQueryTictactoe queryForScoresList];
[service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, GTLTictactoeScores *object, NSError *error) {
NSArray *items = [object items];
// Do something with items.
}];
In the above sample code, the call requests a list of all
Score
objects on the server and passes the result to a callback. If
queryForScoresList
required parameters, or a request body, you would set them on the query object. (Xcode’s hinting is very helpful here).
If your iOS app is making calls to an Endpoint that requires authentication, you must Add a Sign-in Dialog to your iOS client.
For more information on making authenticated Endpoints calls, see Adding Authentication to Endpoints .
Adding a sign-in dialog to your iOS client
The client library provides a "ready made" sign-in user interface, which you present to the user by means of the following code:
static NSString *const kKeychainItemName = @"Your App Name";
NSString *kMyClientID = @"your_client_id";
NSString *kMyClientSecret = @"your_client_secret";
GTMOAuth2ViewControllerTouch *viewController;
viewController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:scope
clientID:kMyClientID
clientSecret:kMyClientSecret
keychainItemName:kKeychainItemName
delegate:self
finishedSelector:@selector(viewController:finishedWithAuth:error:)];
[self presentModalViewController:viewController
animated:YES];
You place this code within a method of your view controller. When the user signs in, this code triggers a callback called
finishedWithAuth
. An example implementation follows:
- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
finishedWithAuth:(GTMOAuth2Authentication *)auth
error:(NSError *)error {
[self dismissModalViewControllerAnimated:YES];
if (error != nil) {
// Authentication failed
} else {
// Authentication succeeded
[[self tictactoeService] setAuthorizer:auth];
// Make some API calls
}
}
- (GTLServiceTictactoe *)tictactoeService {
static GTLServiceTictactoe *service = nil;
if (!service) {
service = [[GTLServiceTictactoe alloc] init];
service.retryEnabled = YES;
[GTMHTTPFetcher setLoggingEnabled:YES];
}
return service;
}
As a result of the above code, the service object is set to the user that signed into your application.
Sample client source code
For a complete sample client that illustrates the concepts described above, see the iOS client sample, which uses the sample Tic Tac Toe web backend .