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

在此之前,我已经阅读了这个和这个问题来解决下面的问题,然后再问。

我的问题是,当accessToken过期(无论是因为过期date通过,或手动从我的Facebook的应用程序中心删除应用程序)下面的代码:

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 iOS6集成的Facebook,Facebook的应用程序或Facebook的网站在Safari),其余的运行顺利。

我关心的是为什么我必须做两件事情才能正常工作,以及为什么Facebook SDK第一次无法检测到activeSession和accessToken是无效的。

谢谢大家!

您链接的问题是相关的,特别是Facebook SDK 3.1 – validation访问令牌的错误 ,它解释了设备上的Facebook帐户与服务器不同步的问题(即,如果您从应用程序中心删除应用程序)。 如上所述,在3.1.1中,只有在从服务器获得无效响应时,SDK才会调用设备令牌。 这对于减less服务器往返次数来说是一种折衷。

假设你的代码块在applicationDidFinishLaunching或类似的东西上执行,它将会去else块,因为应用程序以新的会话开始。 当它调用openActiveSessionWithReadPermissions时,iOS 6设备会认为该标记是有效的,并且会让状态变为打开状态,这样就可以执行“执行某些事情”。 只有这样,SDK才会从服务器获取无效响应,并使设备令牌无效。 因此,下一次调用该过程时,会再次提示用户再次进行授权。

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

 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"); } }]; } }]; } }]; }