在 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 客户端库配合使用。