在 iOS 应用中访问 Google API

某些 Google 服务(例如云端硬盘、Gmail 和许多其他服务)提供公开 API,您可以使用这些 API 创建应用,帮助用户处理这些服务中的数据。如需访问这些服务,应用必须实现某个 OAuth 2.0 客户端流程,以征得用户同意并获取访问令牌,从而获得对 API 的访问权限。

您可以使用 Google 登录库(该库可为您实现 OAuth 2.0 流程)来获取已登录用户的访问令牌。

准备工作

您必须完成基本的 Google 登录功能集成

1. 检查已授予哪些范围

在调用 Google API 之前,请使用 GIDGoogleUsergrantedScopes 属性检查已向您的应用授予哪些范围:

Swift

let driveScope = "https://www.googleapis.com/auth/drive.readonly"
let grantedScopes = user.grantedScopes
if grantedScopes == nil || !grantedScopes!.contains(driveScope) {
  // Request additional Drive scope.
}

Objective-C

NSString *driveScope = @"https://www.googleapis.com/auth/drive.readonly";

// Check if the user has granted the Drive scope
if (![user.grantedScopes containsObject:driveScope]) {
  // request additional drive scope
}

根据用户是否已授予特定范围,您可能需要请求额外的范围才能支持特定互动。

2. 申请其他范围

如果您需要请求其他范围,请调用 addScopes:presentingViewController:completionaddScopes:presentingWindow:completion 来请求用户向您的应用授予其他访问权限。

例如,如需请求对用户云端硬盘文件的只读访问权限,请执行以下操作:

Swift

let additionalScopes = ["https://www.googleapis.com/auth/drive.readonly"]
guard let currentUser = GIDSignIn.sharedInstance.currentUser else {
    return ;  /* Not signed in. */
}

currentUser.addScopes(additionalScopes, presenting: self) { signInResult, error in
    guard error == nil else { return }
    guard let signInResult = signInResult else { return }

    // Check if the user granted access to the scopes you requested.
}

Objective-C

NSArray *additionalScopes = @[ @"https://www.googleapis.com/auth/drive.readonly" ];
GIDGoogleUser *currentUser = GIDSignIn.sharedInstance.currentUser;

[currentUser addScopes:additionalScopes
           presentingViewController:self
                         completion:^(GIDSignInResult * _Nullable signInResult,
                                      NSError * _Nullable error) {
    if (error) { return; }
    if (signInResult == nil) { return; }

    // Check if the user granted access to the scopes you requested.
}];

3. 使用新令牌进行 API 调用

为确保您的 Google API 调用始终附有未过期的访问令牌,请将这些调用封装在 refreshTokensIfNeededWithCompletion: 块中:

Swift

currentUser.refreshTokensIfNeeded { user, error in
    guard error == nil else { return }
    guard let user = user else { return }

    // Get the access token to attach it to a REST or gRPC request.
    let accessToken = user.accessToken.tokenString

    // Or, get an object that conforms to GTMFetcherAuthorizationProtocol for
    // use with GTMAppAuth and the Google APIs client library.
    let authorizer = user.fetcherAuthorizer()
}

Objective-C

[currentUser refreshTokensIfNeededWithCompletion:^(
                              GIDGoogleUser * _Nullable user,
                              NSError * _Nullable error) {
    if (error) { return; }
    if (user == nil) { return; }

    // Get the access token to attach it to a REST or gRPC request.
    NSString *accessToken = user.accessToken.tokenString;

    // Or, get an object that conforms to GTMFetcherAuthorizationProtocol for
    // use with GTMAppAuth and the Google APIs client library.
    id<GTMFetcherAuthorizationProtocol> authorizer = [user fetcherAuthorizer];
}];

通过以下方式使用访问令牌调用 API:将访问令牌包含在 REST 或 gRPC 请求的标头中 (Authorization: Bearer ACCESS_TOKEN),或者将提取器授权方与 Google API 客户端库搭配使用。