[英]Google Plus iPhone API sign in and share without leaving app
[英]Google + iPhone API sign in and share without leaving app
我最近在我的应用程序中集成了Google + API,这是一件轻而易举的事,我唯一的问题是,所有内容都要求您离开应用程序然后返回(它使用URL方案)。 这不是我想要的行为,有没有办法直接调用他们的服务,并像LinkedIn API一样做任何我想要的响应?
我真的想避免在safari和我的app之间来回走动。 任何建议/文件表示赞赏。
谢谢,
奥斯卡
来自GOOGLE的更新
今天,我们发布了一个新的Google登录iOS SDK,内置支持通过WebView登录:developers.google.com/identity/sign-in/ios SDK支持发送到处理Sign的众多Google应用中的任何一个在目前,随着WebView后退。 在所有情况下,都避免使用Safari开关,我们认为这是避免应用拒绝的关键因素。 我们期待获得使用新SDK的人们的反馈,并希望它的使用可以取代人们在此期间实施的(巧妙和勤奋)解决方案。
方法BELLOW不再需要
这个方法用一个自定义的UIWebView处理内部登录这个工作并且由APPLE批准
我的应用程序因审查原因而被踢了
"The app opens a web page in mobile Safari for logging in to Google plus,
then returns the user to the app. The user should be able log in without opening
Safari first."
请参阅此链接https://code.google.com/p/google-plus-platform/issues/detail?id=900我通过以下步骤解决了这个问题
1)创建UIApplication的子类,它覆盖openURL:
。H
#import <UIKit/UIKit.h>
#define ApplicationOpenGoogleAuthNotification @"ApplicationOpenGoogleAuthNotification"
@interface Application : UIApplication
@end
.M
#import "Application.h"
@implementation Application
- (BOOL)openURL:(NSURL*)url {
if ([[url absoluteString] hasPrefix:@"googlechrome-x-callback:"]) {
return NO;
} else if ([[url absoluteString] hasPrefix:@"https://accounts.google.com/o/oauth2/auth"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:ApplicationOpenGoogleAuthNotification object:url];
return NO;
}
return [super openURL:url];
}
@end
2)到info.plist,添加Principal类,并为它应用程序(或任何你命名的类)
添加plist键“NSPrincipalClass”,并将值作为主应用程序的类(扩展UIApplication的类,在本例中为Application(参见上面的代码))
3)捕获通知并打开内部webview
当您的自定义Application类发送ApplicationOpenGoogleAuthNotification时,可以在某处(在AppDelegate中)监听它,当您捕获此通知时,打开UIWebView(使用通知传递的URL作为webview的URL)(在我的情况下,LoginViewController侦听对于此通知,当收到时,它会打开一个视图控制器,其中只包含一个连接到委托的webview)
4)在webview中
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[[request URL] absoluteString] hasPrefix:@"com.XXX.XXX:/oauth2callback"]) {
[GPPURLHandler handleURL:url sourceApplication:@"com.google.chrome.ios"n annotation:nil];
// Looks like we did log in (onhand of the url), we are logged in, the Google APi handles the rest
[self.navigationController popViewControllerAnimated:YES];
return NO;
}
return YES;
}
所以,这取决于你想做什么。
登录 :这将始终呼叫另一个应用程序。 如果Google+应用程序已安装,它将会调用它,否则它将退回到Chrome和Safari。
分享/互动帖子 :现在,它总是使用Chrome或Mobile Safari。
检索朋友,编写应用程序活动,检索配置文件信息 :所有这些都是在登录后检索的访问令牌完成的,因此不需要离开应用程序。
虽然相当不受支持,但可以跳过SDK并弹出UIWebView,动态构建OAuth链接并将用户发送到该链接(请查看SDK附带的开源库中的GTMOAuth2ViewControllerTouch)。 下面是一个非常粗略的示例,您可以将其检索回GPPSignIn实例。
但是,您可以保证用户必须输入用户名和密码(可能是第二个因素)。 使用Google+应用,您几乎可以保证已经登录,并且使用Chrome / Safari路线,用户可能已经登录(特别是如果他们使用其他应用与Google+登录)。
这也不涉及共享,所以我强烈建议尽可能使用现有的SDK。 以您希望的方式提交功能请求也是一件好事: https : //code.google.com/p/google-plus-platform/issues/list
@interface ViewController() {
GTMOAuth2ViewControllerTouch *controller;
}
@end;
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
GPPSignIn *signIn = [GPPSignIn sharedInstance];
signIn.clientID = @""; // YOUR CLIENT ID HERE.
signIn.delegate = self;
}
- (IBAction)didTapSignIn:(id)sender {
void (^handler)(id, id, id) =
^(GTMOAuth2ViewControllerTouch *viewController,
GTMOAuth2Authentication *auth,
NSError *error) {
[self dismissViewControllerAnimated:YES completion:^{
[controller release];
}];
if (error) {
NSLog(@"%@", error);
return;
} else {
BOOL signedIn = [[GPPSignIn sharedInstance] trySilentAuthentication];
if(!signedIn) {
NSLog(@"Sign In failed");
}
}
};
controller = [[GTMOAuth2ViewControllerTouch
controllerWithScope:kGTLAuthScopePlusLogin
clientID:[GPPSignIn sharedInstance].clientID
clientSecret:nil
keychainItemName:[GPPSignIn sharedInstance].keychainName
completionHandler:handler] retain];
[self presentViewController:controller animated:YES completion:nil];
}
- (void)finishedWithAuth:(GTMOAuth2Authentication *)auth
error:(NSError *)error {
if (!error) {
UIAlertView * al = [[UIAlertView alloc] initWithTitle:@"Authorised"
message:@"Authorised!"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[al show];
[al release];
}
}
这段代码唯一真正的技巧是它使用[GPPSignIn sharedInstance] .keychainName - 这意味着auth令牌存储在与GPPSignIn按钮相同的keychain条目中,这反过来意味着我们可以使用[[GPPSignIn sharedInstance] trySilentAuthentication]一旦填充完毕,并保持与主库相同的基于回调的流程。
如果未安装Google Plus应用程序,@ PeterLapisu方法效果很好。 然后来自app的传出网址前缀如下:
但是,如果安装了Google App,则会有一个外发网址,前缀列表如下所示:
因此,如果安装了谷歌应用程序,它将与我们的包含webview的应用程序UIViewController同时启动。然后,如果用户成功登录谷歌应用程序,他将被定向回我们的应用程序,ViewController将可见。
为了防止这种情况,应该允许Google App登录用户并将其引导回我们的应用程序。 根据此讨论: https : //code.google.com/p/google-plus-platform/issues/detail?id = 900,Apple允许这样做。
所以在我的实现中,首先我要检查是否安装了Google App:
- (BOOL)openURL:(NSURL*)url {
NSURL *googlePlusURL = [[NSURL alloc] initWithString:@"gplus://plus.google.com/"];
BOOL hasGPPlusAppInstalled = [[UIApplication sharedApplication] canOpenURL:googlePlusURL];
if(!hasGPPlusAppInstalled)
{
if ([[url absoluteString] hasPrefix:@"googlechrome-x-callback:"]) {
return NO;
} else if ([[url absoluteString] hasPrefix:@"https://accounts.google.com/o/oauth2/auth"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:ApplicationOpenGoogleAuthNotification object:url];
return NO;
}
}
return [super openURL:url];
}
编辑:
现在我可以确认我的应用程序最终获得了此解决方案的批准。
我希望它会对某人有所帮助。 它合并了Google+和Gmail示例,完全避免使用Google SignIn Button,即您不会离开应用。
将Google +和Gmail API添加到Google项目中,在您的应用中登录google,就像使用来自OAuth2的GTMOAuth2ViewControllerTouch.xib gmail并将范围设置为Google+:
-(IBAction)dologin{
NSString *scope = kGTLAuthScopePlusLogin;//Google+ scope
GTMOAuth2Authentication * auth = [GTMOAuth2ViewControllerTouch
authForGoogleFromKeychainForName:kKeychainItemName
clientID:kClientID
clientSecret:kClientSecret];
if ([auth refreshToken] == nil) {
GTMOAuth2ViewControllerTouch *authController;
authController = [[GTMOAuth2ViewControllerTouch alloc]
initWithScope:scope
clientID:kClientID
clientSecret:kClientSecret
keychainItemName:kKeychainItemName
delegate:self
finishedSelector:@selector(viewController:finishedWithAuth:error:)];
[[self navigationController] pushViewController:authController animated:YES];
}else{
[auth beginTokenFetchWithDelegate:self didFinishSelector:@selector(auth:finishedRefreshWithFetcher:error:)];
}
}
如果成功登录,则保留身份验证对象,然后在使用google plus服务时使用该身份验证对象:
GTLServicePlus* plusService = [[[GTLServicePlus alloc] init] autorelease];
[plusService setAuthorizer:self.auth];//!!!here use our authentication object!!!
不需要GPPSignIn。
完整的文章在这里: 这是另一种解决方案
使用(新) Google登录iOS SDK 。
当没有Google应用程序来完成登录过程时,SDK本身支持通过WebView登录。 它还支持为此目的分发几个Google应用程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.