ios-google接入


title: ios-google接入
categories: Ios
tags: [ios, google]
date: 2021-02-15 19:58:43
comments: false
mathjax: true
toc: true

ios-google接入


前篇

  • 官方 - https://developers.google.cn/identity/sign-in/ios/start-integrating

google 接入

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

    创建 ios 类型的 client id

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hz8JMeFO-1613393112071)(http://yxbl.itengshe.com/20210215204243-1.webp)]

  2. CocoaPods 引入几个核心库

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

    <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 面板上加入配置

  4. 代码

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

      // 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. 登录, 登出

      // 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 请求成功的话, 会返回这样的字段

    {
          
          
        "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


猜你喜欢

转载自blog.csdn.net/yangxuan0261/article/details/113819080