在Facebook iOS 3.1.1 SDK中处理FBSession openActiveSessionWithReadPermissions的无效accessToken

问题描述:

在任何事情之前,我已经阅读了这个问题,以解决下面的问题和在询问之前

Before anything, I have read both this and this questions to solve the problem below and before asking.

我的问题是,当accessToken已过期(由于到期日期过去,或手动删除我的Facebook应用中心的应用程序)下面的代码: / p>

My problem is that when the accessToken gets expired (either because the expiration date passes, or manually by deleting the app from my Facebook's App Center) the following code:

if ([[FBSession activeSession] isOpen]) {
        //do something
    }
else {
        [FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
            if(FB_ISSESSIONOPENWITHSTATE(status)) {
                //do something
            }
          }
       }];
     }

获取FBSession.activeSession的else块,但是当做某事'执行accessToken是无效的,所以请求得到错误:HTTP状态代码:400.
当我尝试完成整个过程两次,FBSession要求许可(UIAlertView for iOS6集成的Facebook,Facebook应用程序或Facebook网站在Safari),其余的运行顺利。

gets in the else block with FBSession.activeSession open but when the 'do something' is executed the accessToken is invalid so the request gets Error: HTTP status code: 400. When I try to do the whole procedure twice immediately the FBSession asks for permission (either UIAlertView for iOS6 integrated facebook, Facebook App or Facebook website in Safari) and the rest runs smoothly.

我的关注是为什么我必须做一切两次,以及为什么Facebook SDK无法首次检测到activeSession和accessToken无效。

My concern is why I have to do everything twice to work well and why Facebook SDK cannot detect in the first time that the activeSession and accessToken are invalid.

提前谢谢!

p>您链接的问题是相关的,特别是 Facebook SDK 3.1 - 验证错误访问令牌,它解释了设备上的Facebook帐户出现的问题与服务器同步(即,如果您从App Center中删除了该应用程序)。如上所述,在3.1.1中,只有当SDK从服务器获取无效响应时,SDK才会调用更新设备令牌。这是为了方便少量到服务器的往返的折扣。

The questions you linked are relevant, especially Facebook SDK 3.1 - Error validating access token which explains the problem where the Facebook account on the device is out of sync with the server (I.e., if you deleted the app from App Center). As mentioned there, in 3.1.1 the SDK will call to renew the device token only when it gets the invalid response from the server. This is a trade off in convenience for less round-trips to the server.

假设你的代码块在applicationDidFinishLaunching或类似的东西上执行,它将转到其他块因为应用程序以新会话开始。当它调用openActiveSessionWithReadPermissions时,iOS 6设备认为令牌是有效的,并且将让状态进入Open,所以执行做某事。只有SDK才能从服务器获取无效的响应,并使设备令牌无效。因此,下一次调用该过程时,它会提示用户适当地再次授权。

Assuming your code block is executed on applicationDidFinishLaunching or something similar, it will go to the else block because the app starts with a new session. When it calls openActiveSessionWithReadPermissions, the iOS 6 device thinks the token is valid and will let the state go to Open, so then your "do something" gets executed. Only then does the SDK get the invalid response from the server and invalidate the device token. As a result, the next time the procedure is called, it will prompt the user appropriately to authorize again.

这是有意的。现在,如果错误代码描述了无效令牌,您可以考虑在应用程序中自动重试。例如,请参阅Scrumptious示例postOpenGraph重试代码。在你的情况下,它可能看起来更接近于(我用requestForMe作为演示的做某事):

This is intentional. For now, you can consider a automatic retry in your application if the error code describes an invalid token. For example, see the Scrumptious sample postOpenGraph retry code. In your case, it may look closer to something like (I used requestForMe as the "do something" for demonstration purposes):

else {
    [FBSessionopenActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
        if(FB_ISSESSIONOPENWITHSTATE(status)) {
            //do something
            [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
                if (!error){
                    NSLog(@"success on first try");
                } else if ([[error userInfo][FBErrorParsedJSONResponseKey][@"body"][@"error"][@"code"] compare:@190] == NSOrderedSame) {
                    //requestForMe failed due to error validating access token (code 190), so retry login
                    [FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
                        if (!error){
                            //do something again, or consider recursive call with a max retry count.
                            NSLog(@"success on retry");
                        }
                    }];
                }
            }];
        }
    }];
}