我在ios应用中实施了谷歌登录。现在,我如何验证用户是否已登录,如果没有 - 使用Swift将其返回登录页面?

问题描述 投票:6回答:2

正如我在这个问题的标题中所写 - 我经历了本教程https://developers.google.com/identity/sign-in/ios/sign-in,现在我可以根据他的谷歌凭据登录用户到我的应用程序。

到目前为止我的方式是我有一个ViewController.swift类,代码如下:

class ViewController: UIViewController, GIDSignInUIDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        let background = CAGradientLayer().greenBlue()
        background.frame = self.view.bounds
        self.view.layer.insertSublayer(background, atIndex: 0)
        //GIDSignIn.sharedInstance().uiDelegate = self

        // Uncomment to automatically sign in the user.
        //GIDSignIn.sharedInstance().signInSilently()

    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        GIDSignIn.sharedInstance().uiDelegate = self

        GIDSignIn.sharedInstance().signInSilently()
    }

    @IBAction func didTapSignOut(sender: AnyObject) {
        GIDSignIn.sharedInstance().signOut()
    }

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

    func signInWillDispatch(signIn: GIDSignIn!, error: NSError!) {
        print("Nothing!")
    }

    // Present a view that prompts the user to sign in with Google
    func signIn(signIn: GIDSignIn!,
        presentViewController viewController: UIViewController!) {
            self.presentViewController(viewController, animated: true, completion: nil)
    }

    // Dismiss the "Sign in with Google" view
    func signIn(signIn: GIDSignIn!,
        dismissViewController viewController: UIViewController!) {
            self.dismissViewControllerAnimated(true, completion: nil)
    }
}

在我的AppDelegate.swift类中,我有:

class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {

    var window: UIWindow?


    func application(application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
            // Initialize sign-in
            var configureError: NSError?
            GGLContext.sharedInstance().configureWithError(&configureError)
            assert(configureError == nil, "Error configuring Google services: \(configureError)")

            GIDSignIn.sharedInstance().delegate = self

            return true
    }

    // [START openurl]
    func application(application: UIApplication,
        openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
            return GIDSignIn.sharedInstance().handleURL(url,
                sourceApplication: sourceApplication,
                annotation: annotation)
    }
    // [END openurl]

    @available(iOS 9.0, *)
    func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
        return GIDSignIn.sharedInstance().handleURL(url,
            sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as! String?,
            annotation: options[UIApplicationOpenURLOptionsAnnotationKey])
    }

    // [START signin_handler]
    func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
        withError error: NSError!) {
            if (error == nil) {
                print("Signed in!")
            } else {
                print("\(error.localizedDescription)")

            }
    }
    // [END signin_handler]

    // [START disconnect_handler]
    func signIn(signIn: GIDSignIn!, didDisconnectWithUser user:GIDGoogleUser!,
        withError error: NSError!) {
            // Perform any operations when the user disconnects from app here.
            // [START_EXCLUDE]
            NSNotificationCenter.defaultCenter().postNotificationName(
                "ToggleAuthUINotification",
                object: nil,
                userInfo: ["statusText": "User has disconnected."])
            // [END_EXCLUDE]
    }
}

我的故事板看起来如下:

enter image description here

在左边我有一个带有标记谷歌按钮的ViewController(这是白色的,因此它在这里不可见 - 抱歉!)在右边我有一个主要的TabController视图,其中包含我的应用程序的整个逻辑(到目前为止它很空) :

class TabController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let background = CAGradientLayer().greenBlue()
        background.frame = self.view.bounds
        self.view.layer.insertSublayer(background, atIndex: 0)
    }

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

}

现在它的工作原理如下:

我运行应用程序并看到谷歌按钮登录。我登录并确认所有内容 - 没有任何变化,我没有移动到第二个屏幕(TabController)。我只是留在这个视图,我可以继续点击谷歌按钮 - 没有任何变化,因为我已经登录。

我希望在用户打开我的应用程序时以及未登录时实现这种情况 - 他看到了ViewController屏幕。当他登录时 - 他看到了TabController屏幕。而且当他之前已经登录并打开我的应用程序 - 他立即跳转到TabController并跳过ViewController页面。我怎样才能实现它?

我怀疑我必须在我的故事板上标记我的TabControllerinitial view controller,但是登录屏幕怎么样?

=====编辑

继Mac Bellingrath回答我在appDelegate.swift类中修改了我的函数,现在它看起来像这样:

func application(application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Initialize sign-in
        var configureError: NSError?
        GGLContext.sharedInstance().configureWithError(&configureError)
        assert(configureError == nil, "Error configuring Google services: \(configureError)")

        GIDSignIn.sharedInstance().delegate = self

        /* check for user's token */
        if GIDSignIn.sharedInstance().hasAuthInKeychain() {
            /* Code to show your tab bar controller */
            print("user is signed in")
            let sb = UIStoryboard(name: "Main", bundle: nil)
            if let tabBarVC = sb.instantiateViewControllerWithIdentifier("TabController") as? UITabBarController {
                window!.rootViewController = tabBarVC
            }
        } else {
            print("user is NOT signed in")
            /* code to show your login VC */
            let sb = UIStoryboard(name: "Main", bundle: nil)
            if let tabBarVC = sb.instantiateViewControllerWithIdentifier("ViewController") as? ViewController {
                window!.rootViewController = tabBarVC
            }
        }

        return true
}

现在,当我运行应用程序并且用户之前已经登录时 - 我看到了tabController视图。如果他之前没有签到 - 我看到了ViewController视图。它几乎像一个魅力,但我意识到,无论我写if GIDSignIn.sharedInstance().hasAuthInKeychain() {if !GIDSignIn.sharedInstance().hasAuthInKeychain() {它总是打印出消息user is signed in,所以有些东西仍然不对...

ios swift google-signin
2个回答
18
投票

根据Google's documentation的说法,您似乎可以使用GIDSignIn的实例方法hasAuthInKeychain()来检查用户当前是否已登录或者是否已将先前的身份验证保存在钥匙串中。

所以,在你的AppDelegate中

func application(application: UIApplication,didFinishLaunchingWithOptions                    launchOptions: [NSObject: AnyObject]?) -> Bool {

你可以写一些类似的东西:

GIDSignIn.sharedInstance().delegate = self
/* check for user's token */
if GIDSignIn.sharedInstance().hasAuthInKeychain() {
/* Code to show your tab bar controller */
} else {
/* code to show your login VC */
}

例如,如果我们的用户已登录:

let sb = UIStoryboard(name: "Main", bundle: nil)
if let tabBarVC = sb.instantiateViewControllerWithIdentifier("MainTabBarVC") as? UITabBarController {
window.rootViewController = tabBarVC
}

*用UITabBarController替换你的UITabBarController子类。

当然,有很多方法可以改变流程。查看故事板参考和多个故事板。


0
投票

Mac Bellingrath给出了验证用户登录的完美答案。

检查用户登录的备用方法。

以下是Objective-C中的示例代码,您可以根据需要转换代码。

此示例代码仅供您参考。

    // The authentication object for the current user, or |nil| if there is currently no logged in user.
    // Here you can get current user object
    GIDGoogleUser *googleUser = [[GIDSignIn sharedInstance] currentUser];

    if (googleUser) {
        // Get new token from google and send to server
        NSString *strToken = googleUser.authentication.idToken;
    }
    else {
        // present login screen here
        [self presentLoginScreen];
    }

0
投票
let googleUser = GIDSignIn.sharedInstance().isCurrentUser

if googleUser != nil {
// Get new token from google and send to server
let strToken = googleUser.authentication.idToken
} else {
// present login screen here
presentLoginScreen()
}
© www.soinside.com 2019 - 2024. All rights reserved.