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

ran*_*er1 6 ios swift google-signin

正如我在这个问题的标题中写的那样 - 我浏览了本教程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)
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的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]
    }
}
Run Code Online (Sandbox Code Playgroud)

我的故事板看起来如下:

在此输入图像描述

在左边我有一个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.
    }

}
Run Code Online (Sandbox Code Playgroud)

现在它的工作原理如下:

我运行应用程序并看到谷歌按钮登录.我登录并确认所有内容 - 没有任何变化,我没有移动到第二个屏幕(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
}
Run Code Online (Sandbox Code Playgroud)

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

Mac*_*ath 18

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

所以,在你的AppDelegate中

func application(application: UIApplication,didFinishLaunchingWithOptions                    launchOptions: [NSObject: AnyObject]?) -> Bool {
Run Code Online (Sandbox Code Playgroud)

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

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 */
}
Run Code Online (Sandbox Code Playgroud)

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

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

*用UITabBarController替换你的UITabBarController子类.

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