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

Osc*_*mez 14 iphone google-plus

我最近在我的应用程序中集成了Google + API,这是一件轻而易举的事,我唯一的问题是,所有内容都要求您离开应用程序然后返回(它使用URL方案).这不是我想要的行为,有没有办法直接调用他们的服务,并像LinkedIn API一样做任何我想要的响应?

我真的想避免在safari和我的app之间来回走动.任何建议/文件表示赞赏.

谢谢,

奥斯卡

Pet*_*isu 55

来自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."
Run Code Online (Sandbox Code Playgroud)

请参阅此链接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
Run Code Online (Sandbox Code Playgroud)

.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
Run Code Online (Sandbox Code Playgroud)
  • 这基本上可以防止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;
}
Run Code Online (Sandbox Code Playgroud)
  • 或者用于处理响应的simmilar代码
  • 来自上面代码的com.XXX.XXX:/oauth2callback,替换为您的公司和应用程序标识符,例如"com.company.appname:/ oauth2callback"
  • 您可能希望使用@"com.apple.mobilesafari"作为sourceApplication参数

  • @PeterLapisu和其他人 - 今天,我们发布了一个新的Google登录iOS SDK,内置支持通过WebView登录:https://developers.google.com/identity/sign-in/ios SDK支持发送适用于处理登录的许多Google应用程序中的任何一个,以及之后的WebView后备.在所有情况下,都避免使用Safari开关,我们认为这是避免应用拒绝的关键因素.我们期待获得使用新SDK的人们的反馈,并希望它的使用可以取代人们在此期间实施的(巧妙和勤奋)解决方案. (2认同)

Ian*_*ber 12

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

登录:这将始终呼叫另一个应用程序.如果Google+应用程序已安装,它将会调用它,否则它将退回到Chrome和Safari.

分享/互动帖子:现在,它总是使用Chrome或移动版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];
  }
}
Run Code Online (Sandbox Code Playgroud)

这段代码唯一真正的技巧是它使用[GPPSignIn sharedInstance] .keychainName - 这意味着auth令牌存储在与GPPSignIn按钮相同的keychain条目中,这反过来意味着我们可以使用[[GPPSignIn sharedInstance] trySilentAuthentication]一旦填充完毕,并保持与主库相同的基于回调的流程.