iOS 接入 Google、Facebook 登录(二)

avatar
奇舞团移动端团队 @奇舞团

级别:★☆☆☆☆
标签:「iOS 接入 Google、Facebook 登录」「iOS Google 登录」「iOS Facebook 登录」
作者: WYW
审校: QiShare团队


前言:
笔者在 iOS 接入 Google、Facebook 登录(一) 中分享了使用 Firebase 接入 Google、Facebook 登录相关的内容,在本文中,笔者将分享直接接入 Google、Facebook 登录SDK的内容。

关于在 Google、Facebook 开放平台创建应用、项目中需要做的配置,笔者已经在上一篇文章 iOS 接入 Google、Facebook 登录(一) 中说明。本文中不再说明。

iOS 接入 Google、Facebook 登录(一) 是使用的Firebase 接入的 Google、Facebook 登录。上一篇文章中的 Google、Facebook 的登录按钮都是使用的 Firebase 封装好的。如果我们想要自定义 Google、Facebook 按钮,我们可在点击自定义按钮的时候,调用登录相关 API 即可。

一、接入 Google 登录SDK

下边笔者先放置了 Google、Facebook 登录的效果图。

1. Google、Facebook 登录效果图

GoogleFacebookLoginDemo.gif

下边笔者分享下集成 Google 登录 SDK 的方式、过程及部分 API。

2. 集成 Google 登录 SDK

集成 Google 登录 SDK,Google 官方提供了2种方式,分别是使用 Cocoapods 和 直接拖拽相应 Framework 和相关资源文件到项目。

2.1 Cocoapods 方式集成 Google 登录 SDK

Podfile 内容如下:

pod 'GoogleSignIn', '~> 5.0.2'
2.2 直接下载 Google 登录的 Framework

直接下载 Google 登录的 Framework 时,我们需要链接所需的 Framework,及做相关 Objc 配置等。具体流程及更多可选的 Google 登录的 Framework 可查看 Get the Google Sign-In SDK for iOS

3. 接入Google 登录相关操作

3.1 在应用启动的时,初始化 Google SDK
#import <Firebase.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
	[GIDSignIn sharedInstance].clientID = kGoogleClientID;
    // 其他代码... 
    return YES;
}
3.2 Google 登录需要在如下代理方法中做处理
3.2.1 AppDelegate.m 文件中的代理方法
- (BOOL)application:(nonnull UIApplication *)application
            openURL:(nonnull NSURL *)url
            options:(nonnull NSDictionary<NSString *, id> *)options {
    
    return [[GIDSignIn sharedInstance] handleURL:url];
}

//  ios(4.2, 9.0)
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation {
    if ([url.absoluteString containsString:kGoogleClientID]) {
        return [[GIDSignIn sharedInstance] handleURL:url];
    }
    return NO;
}
3.2.2 SceneDelegate.m 中的代理方法
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts  API_AVAILABLE(ios(13.0)){
    
    UIOpenURLContext *openURLContext = URLContexts.allObjects.firstObject;
    if ([openURLContext.URL.absoluteString containsString:kGoogleClientID) {
        [[GIDSignIn sharedInstance] handleURL:openURLContext.URL];
    }
}
3.3 Google 登录按钮相关代码及处理 Google 登录成功失败结果相关代码
#import <GoogleSignIn/GoogleSignIn.h>

// 遵守代理 <GIDSignInDelegate>

// 设置代理
[GIDSignIn sharedInstance].delegate = self;
// 必须设置 否则会Crash
[GIDSignIn sharedInstance].presentingViewController = self;

// 点击自定义的 Google 登录按钮 可以调用如下API
[[GIDSignIn sharedInstance] signIn];



// 实现代理方法
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error {
    if (!error) {
        NSLog(@"用户ID:%@", user.userID);
    } else {
        NSLog(@"%@", error.debugDescription);
    }
}

在上述代码中,当我们点击的自定义的 Button 调用 [[GIDSignIn sharedInstance] signIn]; ,便会执行 Google 登录的流程。Google 登录成功或失败的结果会在 - (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error 的代理方法中回调。

3.5 Google 退出 API
[[GIDSignIn sharedInstance] signOut];

下边笔者分享下接入 Facebook 登录 SDK 的方式、过程、部分 API 及遇到的切换 Facebook 账号问题。

二、 接入 Facebook 登录SDK

1. 集成 Facebook 登录 SDK

Facebook 开放平台提供了4种方式,Swift Package Manager、Cocoapods、Carthage、直接下载 Facebook 登录 SDK。下边笔者简单说明下 Cocoapods 集成方式及 直接下载 Facebook 登录SDK

如需使用其他集成方式可查看 iOS 版 Facebook 登录 — 快速入门

在第2部分设置开发环境的位置,在使用 iOS 版 Facebook 登录之前,请先设置您的开发环境的下方可以选择集成方式,Facebook 官方文档就会显示相应的集成说明。

1.1 Cocoapods 方式集成 Facebook 登录 SDK

Podfile 内容如下:

pod 'FBSDKLoginKit', '~>6.0.0'
1.2 直接下载 Facebook 登录 SDK

下载地址:Facebook 登录 SDK

2. 接入 Facebook 登录相关操作

2.1 在应用启动的时,调用准备使用 Facebook SDK 的代码及初始化 Facebook SDK 的代码
 // 为了使用 Facebook SDK 应该调用如下方法
[[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
// 注册 FacebookAppID
[FBSDKSettings setAppID:kFacebookAppID];
2.2 Facebook 登录需要在如下代理方法中做处理

如下代理方法用于手机端安装了 Facebook 的情况下,从我们的应用跳转到 Facebook ,然后从 Facebook 跳转回我们的应用的时候,移除之前模态出的授权视图。

2.2.1 AppDelegate.m 文件中的代理方法
- (BOOL)application:(nonnull UIApplication *)application
            openURL:(nonnull NSURL *)url
            options:(nonnull NSDictionary<NSString *, id> *)options {
    
    if (@available(iOS 9.0, *)) {
        return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
    } else {
        // Fallback on earlier versions
    }
}

//  ios(4.2, 9.0)
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation {
    if ([url.absoluteString containsString:kFacebookAppID]) {
        return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
    }
    return NO;
}
2.2.2 SceneDelegate.m 中的代理方法
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts  API_AVAILABLE(ios(13.0)){
    
    UIOpenURLContext *openURLContext = URLContexts.allObjects.firstObject;
    if (openURLContext) {
        if ([openURLContext.URL.absoluteString containsString:kFacebookAppID]) {
             [[FBSDKApplicationDelegate sharedInstance] application:UIApplication.sharedApplication openURL:openURLContext.URL sourceApplication:openURLContext.options.sourceApplication annotation:openURLContext.options.annotation];
            return;
        }
    }
}
2.3 Facebook 登录按钮相关代码及处理 Facebook 登录成功失败结果相关代码
#import "FBSDKLoginKit.h"

// 点击 Facebook 登录按钮的时候调用如下代码即可调用 Facebook 登录功能
FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init];

[loginManager logInWithPermissions:@[@"public_profile"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult * _Nullable result, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Process error");
    } else if (result.isCancelled) {
        NSLog(@"Cancelled");
    } else {
        NSLog(@"token信息:%@", result.token);
    }
}];

Facebook 退出登录可以调用如下代码。遇到 Process Error 的时候,也可以试试调用如下退出登录的 API。

FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init];
[loginManager logOut];
2.4 Facebook 切换登录的账号问题

我的同事 SH 在调研过程中,发现了 Facebook授权登录 切换账号不友好的问题。确实如果安装了 Facebook 的情况下,用户切换 Facebook 账号可以通过在 Facebook 客户端去修改登录的账号。但是如果没有安装 Facebook 客户端,用户就无法切换Facebook账号了。因为仔细看看本文第一部分的呈现的效果图的时候,可以发现,Facebook 登录 没有像 Google 登录那样提供一个切换账号的方式(使用账号)。

针对 Facebook切换账号的问题,笔者后来也尝试过Facebook 的 logOut([[[FBSDKLoginManager alloc] init] logOut];)、Facebook SDK 的 Revoke Permissions 不过都没有解决切换账号的问题,在 Facebook 登录 SDK 的 issues 中发现,相关功能在Facebook SDK 的roadmap 中,及目前Facebook 登录SDK 并不支持切换账号。 相关网址:Can't login with another account after logout

目前可考虑的解决切换 Facebook 账号的方式

针对切换账号问题,笔者后来发现,如果用户没有安装Facebook 的客户端。又想切换 Facebook 账号进行授权登录的时候,可以通过 “设置” -> “Safari 浏览器” -> ”高级“ -> ”网站数据“ -> 右上角”编辑“ -> 删除facebook.com 的数据。

经过上述操作,用户就可以在使用 Facebook 登录授权的时候,FacebookSDK 会要求再次输入账号密码。

在此过程中如果遇到 FacebookSDK 报出的 Process Error的问题。可以调用 FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init]; [loginManager logOut]; 调用退出 Facebook 账号来解决问题。

下边笔者分享下使用 Firebase 接入 Google、Facebook 登录和直接接入 Google、Facebook 登录SDK 在包体积、编译时间、现有项目考虑的比较。

三、 对比Firebase 接入Google、Facebook 登录和直接接入 Google、Facebook 登录

下边笔者对使用 Firebase 接入 Google(方便起见记作方式1)、Facebook 登录和直接接入 Google、Facebook 登录(方便起见记作方式2)做了个个人理解的对比。

1. 打出来的安装包体积方面

方式1的Podfile 内容:

pod 'Firebase/Auth', '~> 6.16.0'
pod 'GoogleSignIn', '~> 5.0.2'
pod 'FBSDKLoginKit', '~>6.0.0'

方式2的 Podfile 内容:

pod 'FBSDKLoginKit', '~>6.0.0'
pod 'GoogleSignIn', '~> 5.0.2'

方式1 和 方式2 的 pod 的内容会多一个 Firebase/Auth

方式1 和 方式2 的pods 项目图比较

方式1相比较方式2来说。方式1需要 pod Firebase 封装的 Google、Facebook 的部分代码、图片及本地化字符串等资源文件。所以笔者当前调研的情况方式1会比方式2的 Pods 大4MB左右。笔者打出来相应的开发的 ipa 包比较了一下,方式1 会比方式2的 ipa 包大 1.1MB 左右。

ipaBigSmall.png

注意:最开始笔者调研的时候,写方式1的 Podfile 内容的时候,pod 的内容比较多,最终方式1相比较方式2来说,打出来的 ipa 包要大 7MB 多。所以如果使用 Firebase 接入 Google、Facebook 登录的话,一定要仔细看文档,看清楚需要 pod 的内容。

编译时间相比之下,方式1也会比方式2长。

2. 编译时间方面对比

因为笔者尚不了解编译时间的衡量,只在终端输入过如下命令

defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES

并在 Xcode 的顶部看见过项目编译时间。

下图是笔者在对比的项目非首次编译的情况下,方式1和方式2编译时间长短情况。

CompileTime.png

笔者尝试了多次,发现方式1总会比方式2的编译时间长一些,所以如果考虑减少编译时间的话,可以考虑直接使用 Google、Facebook 登录 SDK。

3. 现有项目考虑

3.1 使用 Firebase 接入Google、Facebook 登录SDK

使用 Firebase 接入的 Google、Facebook 登录 SDK,需要使用 Cocoapods 的方式集成 。

3.2 直接接入Google、Facebook 登录SDK

直接接入 Google、Facebook 登录 SDK 的集成方式上更具多样性。 直接接入 Google、Facebook 登录 SDK 时,Google 官方提供了 Cocoapods 及直接下载Framework 的集成方式,Facebook 提供了 Cocoapods、下载 Framework、Swift Package Manager 、Carthage 的集成方式。

四、参考学习网址


了解更多iOS及相关新技术,请关注我们的公众号:

可添加如下小编微信,并备注加入QiShare技术交流群,小编会邀请你加入《QiShare技术交流群》。

小编微信

关注我们的途径有:
QiShare(简书)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公众号)

推荐文章:
iOS 接入 Google、Facebook 登录(一)
Nginx 入门实战 iOS中的3D变换(二)
iOS中的3D变换(一)
WebSocket 双端实践(iOS/ Golang)
今天我们来聊一聊WebSocket(iOS/Golang)
用 Swift 进行贝塞尔曲线绘制
Swift 5.1 (11) - 方法
Swift 5.1 (10) - 属性
奇舞团安卓团队——aTaller
奇舞周刊