用FBSDK登录,无法执行segue

时间:2015-10-16 10:44:26

标签: ios swift login segue fbsdk

我已经安装了 Facebook SDK ,遵循了所有要求,因为我可以从用户的Facebook帐户中提取数据,但是我无法在记录后执行segue英寸

我收到错误消息:

警告:Attempt to present <viewController1> on <FBSDKContainerViewController> whose view is not in the window hierarchy!

以下是我的代码:

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


    if (FBSDKAccessToken.currentAccessToken() == nil) {

        print("not logged in")
    }
    else {

        print("logged in")
    }


    let loginButton = FBSDKLoginButton()
    loginButton.readPermissions = ["public_profile", "email", "user_friends"]
    loginButton.center = self.view.center
    loginButton.delegate = self
    self.view.addSubview(loginButton)
}

 func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {


    if ((error) != nil)
    {

    }
    else if result.isCancelled {

    }
    else {

         if result.grantedPermissions.contains("email")
        {
            // Do work

            returnUserData()
            addViewHierarchy()

          //  self.performSegueWithIdentifier("signUpFollowPage", sender: self)


        }
    }
}

任何人都可以提供帮助? 感谢

4 个答案:

答案 0 :(得分:7)

我一直在努力解决同样的问题(尽管我正在使用FBSDKLoginManager的{​​{1}})。

虽然问题似乎是在解决Safari Web视图之前调用了回调(或logInWithReadPermissions委托调用),但我找不到一个好的解决方案。

我(可怕的)答案是推迟segue,让didCompleteWithResult时间自然被解雇。在你的情况下:

FBSDKContainerViewController

可能会有更短的延迟。

这让我觉得Facebook登录SDK有一个错误。如果我找时间,我可以查看SDK source。幸运的是,我正在开发的应用程序直到新的一年才会发布,所以我希望无论如何都可以在以后的版本中修复该问题。

答案 1 :(得分:1)

您应该使用viewDidAppear()功能并检查FBSDKAccessToken.currentAccessToken

override func viewDidAppear(animated:Bool){
  if FBSDKAccessToken.currentAccessToken() != nil{
     performSegueWithIdentifier("YOUR_SEGUE",sender:self)
  }
}

答案 2 :(得分:0)

我在使用FB登录时遇到了同样的问题。这是我如何解决它。问题是在导航时,FBContainerView仍处于打开状态。使用self.controller将引用FBContainerView而不是Topmost控制器,因此没有导航。我们需要切换回最顶级的控制器,然后执行导航。

你可以在不执行segue的情况下通过从顶级控制器呈现视图控制器来实现这一点

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
    [requestObject requestAPIMethod];
});

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// access the dictionary

让最顶层的控制器定义一个总是返回最顶层控制器的方法

let topController = self.topMostController()
topController.presentViewController(secondController, animated: true, completion: nil)

答案 3 :(得分:0)

我的解决方案与上面的解决方案相似,但是更具确定性(对我来说,更安全)。

此解决方案可确保在展示之前我们是最高的VC。

                Timer.scheduledTimer(withTimeInterval: 0.01 / 30.0, repeats: true, block: { (timer) in
                if let app = UIApplication.shared.delegate as? AppDelegate, let window = app.window, let rootVC = window.rootViewController {
                    var topController = rootVC
                    while let nextTop = topController.presentedViewController {
                        topController = nextTop;
                    }
                    if topController == self {
                        // we're good, go for it
                        self.performSegue(withIdentifier: "afterLoginSegue", sender: nil)
                        timer.invalidate()
                    } else {
                        log.debug("waiting to transition until we're presenting...")
                    }
                } else {
                    log.error("couldn't resolve a key variable needed to segue, aborting.")
                    timer.invalidate()
                }
            })

我仍然觉得,一旦呈现的Facebook登录Safari VC消失了,就应该有一种方法来获取回调,但是直到该解决方案问世之前,这是我所能做到的(显然,此代码可以清除并模块化,可以在多个VC中使用,但是您可以将其转储到需要的地方。