ios-google接入

ios-google接入


前篇


google 接入

  1. 创建 OAuth 同意屏幕, 名称会显示在 客户端登录页上, 所以要注意一下命名.

  2. 在 google api 后台获取 ios 类型 client id 和 reversed client id.

    创建 ios 类型的 client id

  3. CocoaPods 引入几个核心库

    1
    pod 'GoogleSignIn', '5.0.2'
  4. info.plist 文件的 <dict>...</dict> 内加入配置, 这里使用的是 reversed client id. (com.googleusercontent.apps 开头的, 不是 client id)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <key>CFBundleURLTypes</key>
    <array>
    <dict>
    <key>CFBundleTypeRole</key>
    <string>Editor</string>
    <key>CFBundleURLSchemes</key>
    <array>
    <string>com.googleusercontent.apps.1086111-l3k4nlbbb</string>
    </array>
    </dict>
    </array>

    或者在 info.plist 的 GUI 面板上加入配置

  5. build settings -> Other Linker Flags 中加入 -ObjC

  6. 代码

    1. 在 app 启动完后初始化 sdk

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      // AppDelegate.m  
      @implementation AppDelegate

      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      [GIDSignIn sharedInstance].clientID = @"1086444997895-l3k4nl4oq9allsq7rga9adiaeth2g8n9.apps.googleusercontent.com"; // client id
      [GIDSignIn sharedInstance].delegate = GGHelper.shareInstance;
      return YES;
      }

      - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options{
      [[GIDSignIn sharedInstance] handleURL:url];
      return YES;
      }
    2. 登录, 登出

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      // GGHelper.h
      #import <GoogleSignIn/GoogleSignIn.h>
      @interface GGHelper : NSObject <GIDSignInDelegate> // GIDSignInDelegate 登录结果回调
      +(instancetype) shareInstance;
      +(void)login:(CodeIdFn)cb;
      +(void)logout:(CodeIdFn)cb;
      @end

      // GGHelper.m
      #import "GGHelper.h"
      #import "Tool.h"
      @implementation GGHelper
      static GGHelper *_sharedIns = nil;
      +(instancetype) shareInstance {
      static dispatch_once_t onceToken;
      dispatch_once(&onceToken, ^{
      _sharedIns = [[self alloc] init] ;
      }) ;
      return _sharedIns ;
      }

      +(void)login:(CodeIdFn)cb {
      [GIDSignIn sharedInstance].presentingViewController = [Tool getRootViewCtrl];
      [[GIDSignIn sharedInstance] signIn]; // 调用这个接口是一定要给 presentingViewController 赋值一个 UIViewController, 不然会闪退, 卧槽
      // [[GIDSignIn sharedInstance] restorePreviousSignIn]; // 自动登录
      }

      +(void)logout:(CodeIdFn)cb {
      [[GIDSignIn sharedInstance] signOut];
      }

      // ------------------------------- 实现 GIDSignInDelegate 的接口
      - (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error {
      if (error != nil) {
      if (error.code == kGIDSignInErrorCodeHasNoAuthInKeychain) {
      // restorePreviousSignIn 自动登录失败会回调到这里.
      NSLog(@"--- didSignInForUser, The user has not signed in before or they have since signed out.");
      } else {
      NSLog(@"--- didSignInForUser, err: %@", error);
      }
      return;
      }
      // Perform any operations on signed in user here.
      NSString *userId = user.userID; // For client-side use only!
      NSString *idToken = user.authentication.idToken; // Safe to send to the server
      NSString *fullName = user.profile.name;
      NSString *givenName = user.profile.givenName;
      NSString *familyName = user.profile.familyName;
      NSString *email = user.profile.email;
      NSLog(@"--- login success, user: %@, fullName: %@", userId, fullName);
      // ...
      }

      - (void)signIn:(GIDSignIn *)signIn didDisconnectWithUser:(GIDGoogleUser *)user withError:(NSError *)error {
      NSLog(@"--- didDisconnectWithUser, err: %@", error);
      }
      @end

服务器校验字段

  • 如果使用 token 请求成功的话, 会返回这样的字段

    1
    2
    3
    4
    5
    {
    "azp": "10864aaa-l3kbbb.apps.googleusercontent.com",
    "aud": "10864aaa-l3kbbb.apps.googleusercontent.com",
    "given_name": "Wilker",
    }

    azp 和 aud 的就是 google api 后台获取的 ios 类型的 client id 值, 所以用 client id 去做是否登录成功的判断.

    这个和 Android 不太一样, Android 返回的这两个值都是 web 类型的 client id.


踩坑

调用登录接口 闪退

调用 [[GIDSignIn sharedInstance] signIn] 闪退, 报错: reason: 'presentingViewController must be set.'

就是需要一定要给 presentingViewController 赋值一个 UIViewController


静态库 方式接入

也就是下载 sdk 的方式接入

由于使用 pod 方式引入的 sdk, 在集成到 unity 的时候发现找不到头文件错误: “GoogleSignIn/GoogleSignIn.h” file not found

无奈只能先使用下载 sdk 静态库压缩包的方式去接入

  1. 将 sdk 内的一下几个资源丢到工程目录里的 ThirdSdk/google_signin_sdk_5_0_2 目录下

    • GoogleSignIn.bundle
    • GoogleSignIn.framework
    • GoogleSignInDependencies.framework
  2. GoogleSignIn.bundle 添加到 主模块 build settings -> Copy Bundle Resources build phase.

  3. 把以下几个系统模块 添加到 主模块 build phases -> Link binary with libraries

    • LocalAuthentication.framework
    • SafariServices.framework
    • AuthenticationServices.framework
    • SystemConfiguration.framework
  4. 在 主模块 中的 build settings -> framework search paths 中加入搜索路径 ThirdSdk/google_signin_sdk_5_0_2