FBSession.openActiveSessionWithReadPermissions没有调用completionHandler。

3

我正在使用Facebook SDK实现OAuth登录,但是FBSession.openActiveSessionWithReadPermissions:allowLoginUI:completionHandler方法没有调用completionHandler,也没有返回“true”,这表明缓存了令牌。除此之外,其他的都似乎很好,只有这里出了问题。这段代码有什么问题吗?

    var completionHandler: FBSessionStateHandler = {

        session, status, error in

        NSLog("token not cached");

        if error {

            // Login failed for some reason, so we notify the delegate.
            self.delegate.didFailOpenningSession?(self, withError: ErrorUtility.error(
                code: .FailedOpenningSession,
                withFacebookError: error
            ));

            // Don't proceed on errors
            return;
        }

        // Session is now open, we should notify the delegate
        self.delegate.didOpenSession?(self);
    };

    NSLog("here");

    // Open the session, prompting the user if necessary. This might send the application to the background
    if FBSession.openActiveSessionWithReadPermissions(["public_profile"], allowLoginUI: true, completionHandler: completionHandler) {

        NSLog("Token cached");

        // If we end up here, the session token must exist, so we now have an open session
        self.delegate.didOpenSession?(self);
    }

编辑:我忘记提到NSLog记录了“here”,但没有记录“Token cached”和“token not cached”

编辑:现在情况有点奇怪。当我的应用程序启动时,我会显示一个带有Facebook登录按钮的屏幕。当用户按下按钮时,上面的代码会被触发。在我授权该应用程序之后,应用程序返回到相同的屏幕(它不应该这样,但在完成处理程序被调用之前,我无法以其他方式完成)。然后我尝试再次按下按钮,现在我确实得到了日志。

这是我得到的:

    here
    token not cached
    here

第一行来自第一次按下按钮,其他两行出现在我第二次按下按钮时。这有什么奇怪的地方吗?"token not cached"和"here"不应该反过来吗?它是从最后一次调用中调用completionHandler吗?
算了,这个问题已经解决了。
另外一个问题。如果我多次按下按钮,我总是得到"token not cached"。我认为它应该被缓存。
3个回答

8

问题已解决。我漏掉了方法AppDelegate.application:handleOpenURL -> Bool。


很高兴听到你找到了它! - TheCodingArt

2

通常是因为在应用程序的application:openURL函数中缺少处理会话的代码导致此问题。这个函数位于AppDelegate.m文件中。Facebook示例提供了以下说明:

 // During the Facebook login flow, your app passes control to the Facebook     iOS app or Facebook in a mobile browser.
// After authentication, your app will be called back with the session information.
// Override application:openURL:sourceApplication:annotation to call the FBsession object that handles the incoming URL
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url     sourceApplication:(NSString *)sourceApplication
 annotation:(id)annotation
{
  return [FBSession.activeSession handleOpenURL:url];
}

2
请先确保您使用的是正确的闭合语法。您没有为块回调提供匹配的闭合回调。
请注意FB会话的块回调为:
^(FBSession *session,
       FBSessionState state, NSError *error)

您应该拥有

    /*function parameters*/){ session, state, error in
//closure declaration goes at the top after the {

//Insert logic here
            NSLog("Token cached");
    }

这将等同于。
FBSession.openActiveSessionWithReadPermissions(permissions, allowLoginUI:true){ session, state, error in

         //callback code body here
}

感谢您的反馈。然而,它并没有解决问题。Swift允许您像您描述的那样传递最后一个参数,但实际上有什么区别呢?我认为闭包仍然会被调用... - André Fratelli
只要正确处理了设置Facebook SDK等所有事项,我上面提到的应该是正确的,并且在从SDK接收响应时应该被调用(您可能需要验证所有Facebook设置并查看是否有其他回调被调用)。我没有意识到您上面的内容是作为闭包语句声明的变量传递的。此时,您将想要验证您的Facebook设置和任何其他可用的回调。为了简化和调试,我首先会删除var...特别是因为它有点冗余。 - TheCodingArt
老实说,根据提供的代码,您所拥有的似乎是正确的。 - TheCodingArt
我也同意 =\ 没有发现任何问题,但您能否看一下我的编辑? - André Fratelli
这里<- 这将首先被调用,因为您正在创建一个变量作为回调,然后调用您的日志,然后再传递完成闭包调用处理程序。 回调触发了未缓存的令牌...请记住(此回调可能会延迟。您应该检查它是时间问题还是连续两次调用FB SDK引起的问题)。 这里再次被调用,因为您正在再次调用相同的代码...与第一个here被调用的原因相同。 - TheCodingArt
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接