Cloud Endpoints Frameworks v1 has been deprecated and will be shut down on August 2, 2018. We recommend that you use the latest version of this feature, which is renamed to Cloud Endpoints Frameworks for App Engine. This new version supports App Engine standard environment, provides lower latency, and has better integration with App Engine. For more details, see Migrating to 2.0.
This page describes how to call a backend API built with a Cloud Endpoints Framework from an iOS app.
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 REST format following the instructions provided in Generating Discovery Docs for iOS.
-
On a system running a recent version of Mac OSX that has the Xcode development environment installed, clone a copy of the Google APIs Client Library as follows:
git clone --recursive https://github.com/google/google-api-objectivec-client-for-rest.git
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-for-rest/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 REST 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-rest.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-for-rest/Source/GTLRCore.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 might want 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. 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 using the instructions provided by that SDK.
-
Your project needs to include the
foo.h
&foo_Sources.m
files generated from ServiceGenerator, which you ran previously, wherefoo
is your API name. 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";
// Client secret is not required, and can be left blank.
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.