使用 GIDSignIn 使用另一个 Google 应用程序登录时不获取 Google 用户

Not fetch Google user when handle sign in with another Google app using GIDSignIn

我正在使用 Google Sign-In for iOS 并且在使用模拟器时它工作正常,因为没有安装 google 应用程序并且正在获取用户,但是当使用我的 iPhone 6 设备时打开 youtube (其中有一些注册帐户)用于处理登录。 之后,当返回应用程序代码时,不要进入此功能:

-(void)signIn:(GIDSignIn *) signIn 
    didSignInForUser:(GIDGoogleUser *)
    user withError:(NSError *) error

任何人都可以帮助我我不能使用其他功能进行登录我必须调用 [[GIDSignIn sharedIstance] signIn] 并且此功能检测是否安装了另一个 google 应用程序并自动打开另一个 google 应用程序或网页视图。

我通过正确设置 GIDSignIn 实例的一些属性解决了这个问题。例如:

GIDSignIn*sigNIn=[GIDSignIn sharedInstance];
[sigNIn setDelegate:self];
[sigNIn setUiDelegate:self];
sigNIn.shouldFetchBasicProfile = YES;
sigNIn.allowsSignInWithBrowser = NO;
sigNIn.allowsSignInWithWebView = YES;
sigNIn.scopes = @[@"https://www.googleapis.com/auth/plus.login",@"https://www.googleapis.com/auth/userinfo.email",@"https://www.googleapis.com/auth/userinfo.profile"];
sigNIn.clientID =@"xxxxxxxxxxxxxxxxxxxxxxxgai.apps.googleusercontent.com";
[sigNIn signIn];

我假设您在自己的服务器上使用 GIDSignin,这要求您在 GIDSignin 中包含一个 serverclientID。这将迫使我的应用程序尝试使用 youtube 或 google plus 登录,而不是打开网络视图甚至浏览器。这将 return GIDSigninError=-1 "a potentially recoverable error.." 并且不允许用户登录。

我解决这个问题的方法是通过覆盖 UIApplication 的 canOpenURL 函数在打开它们之前阻止来自 google 或 youtube 的 URL。我通过子类化 UIApplication 并像这样实现 canOpenURL 来做到这一点:

@interface MyApp : UIApplication
- (BOOL)canOpenURL:(NSURL *)url;
@end

@implementation MyApp
- (BOOL)canOpenURL:(NSURL *)url
{
    if ([[url scheme] hasPrefix:@"com-google-gidconsent"] || [[url scheme] hasPrefix:@"com.google.gppconsent"]) {
        return NO;
    }
    return [super canOpenURL:url];
}
@end

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, NSStringFromClass([MyApp class]), NSStringFromClass([AppDelegate class]));
    }
}

请注意,通常在 argv 之后会有一个 nil,但这是放置 UIApplication 子类的地方。这也是您可以使用自己的 AppDelegate 子类的方式。

另一种解决方案是在 UIApplication 上创建一个覆盖 canOpenURL 的类别,并使用 swizzling 在您的自定义 canOpenURL 中调用原始实现。这是一篇关于 swizzling 的好文章: https://blog.newrelic.com/2014/04/16/right-way-to-swizzle/

不过我必须警告您,这两个解决方案都是 hack,您必须非常小心这样做可能对您的应用程序产生的副作用。我什至不确定苹果会接受这个。

import UIKit
import GoogleSignIn
import Google

class ViewController: UIViewController,GIDSignInUIDelegate, GIDSignInDelegate {

override func viewDidLoad() {
    super.viewDidLoad()
    let gidSingIn = GIDSignIn()

    GIDSignIn.sharedInstance().uiDelegate = self
        gidSingIn.delegate = self
    GIDSignIn.sharedInstance().delegate = self

    var configureError:NSError?
    GGLContext.sharedInstance().configureWithError(&configureError)

    assert(configureError == nil, "Error configuring Google services: \(configureError)")


    let button = GIDSignInButton(frame:CGRectMake(0,0,30, 200))
        button.center = self.view.center
        button.backgroundColor = UIColor.blueColor()
       self.view.addSubview(button)



    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func signInGoogle(sender: AnyObject) {

    print("pressed")

}

func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
            withError error: NSError!) {
    if (error == nil) {
        // Perform any operations on signed in user here.
        print(user.userID)                // For client-side use only!
        print(user.authentication.idToken) // Safe to send to the server
        print(user.profile.name)
        print(user.profile.givenName)
        print(user.profile.familyName)
        print(user.profile.email)
        print(user.authentication.accessToken)
        print(user.profile)
    } else {
        print("\(error.localizedDescription)")
    }
}
func signIn(signIn: GIDSignIn!, didDisconnectWithUser user:GIDGoogleUser!,
            withError error: NSError!) {
}

} // 这是使用 gmail 帐户登录,而不是用于 googleplus。只需在您的控制器中复制并过去。 并在您的 AppDelegate Class

中添加以下功能
func application(application: UIApplication,
                 openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
    var options: [String: AnyObject] = [UIApplicationOpenURLOptionsSourceApplicationKey: sourceApplication!,UIApplicationOpenURLOptionsAnnotationKey: annotation]
    return GIDSignIn.sharedInstance().handleURL(url,
                                                sourceApplication: sourceApplication,
                                                annotation: annotation)
}

我的问题是

func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!, withError error: NSError!)

不再存在,请改用

public func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!)

注意 didSignInForUserdidSignInFor 的区别。 很可能是在将 SDK 更新为 swift 3.

之后