繁体   English   中英

Google + iPhone API登录并分享,无需离开应用

[英]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
  • 这基本上可以防止iOS上的Chrome打开任何内容
  • 我们捕获auth调用并将其重定向到我们的内部UIWebView

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;
}
  • 或者用于处理响应的simmilar代码
  • 来自上面代码的com.XXX.XXX:/oauth2callback,替换为您的公司和应用程序标识符,例如“com.company.appname:/ oauth2callback”
  • 您可能希望使用@“com.apple.mobilesafari”作为sourceApplication参数

所以,这取决于你想做什么。

登录 :这将始终呼叫另一个应用程序。 如果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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM