Overview of Google APIs Client Library for Objective-C
mainGTM Session Fetcher project. For XML-based APIs, developers should use the older gdata-objectivec-client library instead.repository·main·Indexed 21 days ago
https://github.com/google/google-api-objectivec-client-for-restA flexible and efficient Objective-C framework for accessing JSON-based Google APIs, recommended for Apple platforms including iOS, macOS, tvOS, and watchOS. The library provides pre-generated classes for many Google services and includes a ServiceGenerator tool to create custom interfaces from discovery documents. It supports integration via CocoaPods and Swift Package Manager, utilizing GTLRService, GTLRQuery, and GTLRObject as its core class hierarchy.
GTM Session Fetcher project. For XML-based APIs, developers should use the older gdata-objectivec-client library instead.The library maps Google API responses to Objective-C objects.
item.snippet.title).GTLRObject used for collections (lists of items). It provides indexed access via subscripts and supports for loops via the NSFastEnumeration protocol.GTLRServiceTicket is returned when executing a query. It allows you to monitor or cancel the ongoing request.```Objective-C
// Example of iterating over a collection object
GTLRYouTube_PlaylistItemListResponse *playlistItemList = ...;
for (GTLRYouTube_PlaylistItem *item in playlistItemList) {
NSLog(@To avoid fetching unnecessary data, use the fields property on a query to select only the specific fields required. This uses a syntax similar to XPath.
Important Considerations:
kind fields: Always include the kind field for both items and collections in your fields string. The library uses this to correctly instantiate the proper object classes; omitting it may cause the library to incorrectly use the GTLRObject base class.nextPageToken: For collection queries, include nextPageToken if you need to handle pagination.fieldsDescription method on a GTLRObject to get a string describing all set fields, which can serve as a template for your query's fields property.// Example: Requesting only IDs, author emails, and kind for items, plus collection metadata
query.fields = @"items(id,author/email,kind),kind,nextPageToken";The library handles Authorization by allowing you to pass an OAuth 2 authorization object to a service class's setAuthorizer: method.
Important Notes:
GTMSessionFetcher library provides an Objective-C protocol for OAuth 2; any library supporting this protocol can be used.Oauth2 subspec in CocoaPods is intended for interacting with that specific service directly, not for providing the general authentication mechanism for the library.You can attach local, non-server-side data to GTLRObject instances using two methods:
Use the userProperties dictionary to store arbitrary key-value pairs. This data is local to your Objective-C code and is not sent to the server or included in NSKeyedArchiver serialization.
GTLRDrive_File *file = [GTLRDrive_File object];
file.userProperties = @{ @"LocalFileURL" : fileLocalURL };To have your custom subclasses instantiated instead of standard classes during JSON parsing, configure the service's objectClassResolver with a map of kind strings to your surrogate classes.
Service-wide configuration:
GTLRDriveService *service = [[GTLRDriveService alloc] init];
NSDictionary *surrogates = @{
[GTLRDrive_File class] : [MyFile class],
[GTLRDrive_FileList class] : [MyFileList class]
};
NSDictionary *serviceKindMap = [[service class] kindStringToClassMap];
GTLRObjectClassResolver *updatedResolver = [GTLRObjectClassResolver resolverWithKindMap:serviceKindMap
surrogates:surrogates];
service.objectClassResolver = updatedResolver;Single query configuration:
GTLRDriveQuery_FilesList *query = [GTLRDriveQuery_FilesList query];
query.executionParameters.objectClassResolver = updatedResolver;The library uses classes generated from the Google APIs Discovery Service. These generated classes follow a specific hierarchy:
GTLRService: The base class for service implementations.GTLRQuery: The base class for query objects.GTLRObject: The base class for data objects.All service, query, and data classes are derived from these three core types.
Batching allows you to execute multiple unrelated queries in a single request, which is faster than individual executions. You can obtain results using two different patterns:
Best for unrelated methods (e.g., requesting different attributes of a single item). You assign a completionBlock to each query before adding it to the batch.
Error Handling: If a specific query within a batch fails but the batch execution itself succeeds, the error passed to the individual completion block will contain a GTLRErrorObject accessible via [GTLRErrorObject underlyingObjectForError:error].
Best for batches of related methods (e.g., requesting the same attributes for an array of items). The handler receives a GTLRBatchResult containing two dictionaries: successes and failures.
Important:
requestID. You can set a custom ID on the query object before execution.// Example: Using Individual Completion Blocks
GTLRCalendarQuery_EventsList *eventsQuery = [GTLRCalendarQuery_EventsList queryWithCalendarId:calendarID];
eventsQuery.completionBlock = ^(GTLRServiceTicket *callbackTicket, GTLRCalendar_Events *events, NSError *callbackError) {
if (callbackError == nil) {
// Query succeeded
}
};
GTLRBatchQuery *batch = [GTLRBatchQuery batchQuery];
[batch addQuery:eventsQuery];
// Example: Using Unified Batch Completion Handler
GTLRBatchQuery *batchQuery = [GTLRBatchQuery batchQuery];
[batchQuery addQuery:query1];
[batchQuery addQuery:query2];
[service executeQuery:batchQuery completionHandler:^(GTLRServiceTicket *callbackTicket, GTLRBatchResult *batchResult, NSError *callbackError) {
if (callbackError == nil) {
// Step through successes
NSDictionary *successes = batchResult.successes;
for (NSString *requestID in successes) {
GTLRObject *result = [successes objectForKey:requestID];
}
// Step through failures
NSDictionary *failures = batchResult.failures;
for (NSString *requestID in failures) {
GTLRErrorObject *errorObj = [failures objectForKey:requestID];
}
} else {
// The entire batch execution failed
}
}];To develop using CocoaPods, ensure you have CocoaPods 1.12.0 or later installed, along with the cocoapods-generate plugin.
Generate an Xcode project from the podspec using the following command:
pod gen GoogleAPIClientForREST.podspec --local-sources=./ --auto-open --platforms=iosNote: You can change the --platforms option to macos, tvos, or watchos to target different Apple platforms.
pod gen GoogleAPIClientForREST.podspec --local-sources=./ --auto-open --platforms=iosTo integrate using Swift Package Manager (SwiftPM), use the GoogleAPIClientForRESTCore product for the common library parts, and specific products for each service API.
For example, to use the Drive API, depend on the GoogleAPIClientForREST_Drive product.
If you are generating code for your own custom APIs, add GoogleAPIClientForRESTCore to get the supporting runtime, then manually add your generated source files to your Xcode project.
GoogleAPIClientForREST_DriveThe Sources/GeneratedServices directory is updated periodically to reflect the current state of services.
Run the following script to update the services:
Tools/GenerateCheckedInServicesIf a service has issues (e.g., a discovery document is missing or malformed), use the --skip [name] argument to ignore that specific service.
To avoid networking issues, you can generate services from a local checkout of the googleapis/discovery-artifact-manager repository. Use Tools/preferred_paths_from_cache.py to determine the preferred paths. This script also supports a --skip argument.
Example workflow:
If discovery-artifact-manager is checked out as a sibling directory, use this command to generate services while skipping specific problematic paths and explicitly including required admin services:
Tools/GenerateCheckedInServices \
--no-preferred \
`Tools/preferred_paths_from_cache.py --skip poly ../discovery-artifact-manager/discoveries` \
../discovery-artifact-manager/discoveries/admin.directory_v1.json \
../discovery-artifact-manager/discoveries/admin.datatransfer_v1.jsonTools/GenerateCheckedInServicesInstead of replacing an entire item, use a patch query to update only specific fields.
Key behaviors:
GTLRCalendarQuery_CalendarsPatch).[GTLRObject nullValue] in the patch object.patchObjectFromOriginal: on a GTLRObject to automatically generate a patch object containing only the differences between the original and a modified version.// Example: Updating only the name of a calendar
GTLRCalendar_Calendar *patchObject = [GTLRCalendar_Calendar object];
patchObject.summary = newCalendarName;
GTLRCalendarQuery_CalendarsPatch *query = [GTLRCalendarQuery_CalendarsPatch queryWithObject:patchObject calendarId:calendarID];
[service executeQuery:query ...]
// Example: Deleting the location field
GTLRCalendar_Calendar *deleteLocationObject = [GTLRCalendar_Calendar object];
deleteLocationObject.location = [GTLRObject nullValue];
GTLRCalendarQuery_CalendarsPatch *deleteQuery = [GTLRCalendarQuery_CalendarsPatch queryWithObject:deleteLocationObject calendarId:calendarID];
[service executeQuery:deleteQuery ...]Follow these steps to release a new version of the library:
update_version.py script to update all necessary files. The version must be in X.Y.Z format../update_version.py 3.2.1Draft a new release.vX.Y.Z (e.g., v3.2.1) that exactly matches the version provided to the update script.Generate release notes button to assist with the description.pod trunk push --skip-import-validation --skip-tests GoogleAPIClientForREST.podspec./update_version.py 3.2.1