Why Google?
可能确实有人要问,为什么要在iOS上做谷歌的集成?
Sorry,目前来说除了项目需求之外,想不到特别好的理由,也是因为这个需求我才做了登录、Drive、Youtube的集成,个人感觉还是不轻松,觉得有必要分享一下,万一有人会用到呢?
而且,Google有很多好用的产品,万一将来逐渐解锁,我也是很愿意集成到自己的App里。
关于SSO单点登录
引用一篇文章,大致理解一下:
谁都能看懂的单点登录(SSO)实现方式(附源码
Google SSO
Pod
pod 'Google/SignIn'
不使用pod,手动也可以,只不过后续工作会有一些麻烦和不用,不赘述了。
配置App
- 通过上面连接快速注册一个App,填写名称和Bundle ID即可
点击Continue之后会让你选择该app支持的服务,这里我们只选择Sign-In就可以了
然后点击Download GoogleService-Info.plist
进入Google API Console
如图操作:
勾选iOS client for .. 然后点击红圈里的下载后会重新得到一份plist,将该plist中的值替换到GoogleService-Info.plist,主要是REVERSED_CLIENT_ID和CLIENT_ID。
- 将新合成的GoogleService-Info.plist拖入你的project
添加URL Schemes
将如下代码插入到你的info.plist中,YOUR_BUNDLE_ID和YOU_ REVERSED_CLIENT_ID 中的内容自行进行替换,两者都可以在GoogleService-Info.plist中找到
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>YOUR_BUNDLE_ID</string>
</array>
</dict>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>YOU_ REVERSED_CLIENT_ID </string>
</array>
</dict>
</array>
Code
- 在AppleDelegate.m中,添加如下代码(其他部分省略)
@interface AppDelegate ()<GIDSignInDelegate>
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSError* configureError;
[[GGLContext sharedInstance] configureWithError: &configureError];
NSAssert(!configureError, @"Error configuring Google services: %@", configureError);
[GIDSignIn sharedInstance].delegate = self;
return YES;
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary *)options {
return [[GIDSignIn sharedInstance] handleURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
#pragma mark - GIDSignDelegate
- (void)signIn:(GIDSignIn *)signIn
didSignInForUser:(GIDGoogleUser *)user
withError:(NSError *)error {
// 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;
// ...
}
@end
- 登录按钮(以下为示例)
- (void)viewDidLoad {
[super viewDidLoad];
[GIDSignIn sharedInstance].uiDelegate = self;
//Config sign in button
GIDSignInButton *signButton = [[GIDSignInButton alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
[self.view addSubview:signButton];
signButton.center = self.view.center;
}
#pragma mark - GIDSignInUIDelegate
//该代理一般不用实现,除非自己对界面跳转或交互有一些需求
// Implement these methods only if the GIDSignInUIDelegate is not a subclass of
// UIViewController.
// Stop the UIActivityIndicatorView animation that was started when the user
// pressed the Sign In button
- (void)signInWillDispatch:(GIDSignIn *)signIn error:(NSError *)error {
[myActivityIndicator stopAnimating];
}
// Present a view that prompts the user to sign in with Google
- (void)signIn:(GIDSignIn *)signIn
presentViewController:(UIViewController *)viewController {
[self presentViewController:viewController animated:YES completion:nil];
}
// Dismiss the "Sign in with Google" view
- (void)signIn:(GIDSignIn *)signIn
dismissViewController:(UIViewController *)viewController {
[self dismissViewControllerAnimated:YES completion:nil];
}
- 登出
调用
[[GIDSignIn sharedInstance] disconnect];
即可。
关于登出的两个方法
[[GIDSignIn sharedInstance] signOut];
//只做登出操作,不会清除keychain中保存的认证数据
[[GIDSignIn sharedInstance] disconnect];
//登出并断开,清除keychain中保存的认证数据。
//一般由用户的主动登出操作调用该方法。