我正在阅读的任何内容(许多 FB 开发文章和 SO 问题)都没有帮助,所以我想我会在这里发帖。我试图让这一切都与 iOS 6 和 Facebook SDK 3.1.1 一起工作。
我有一个非常基本的设置:我的 iOS 应用程序通过 Facebook 进行身份验证,我将 access_token 传递给我的服务器,用户现在已登录到我的应用程序。他们唯一能做的与 facebook 相关的事情就是在他们的墙上贴一些东西。我正在使用旧版 Dialog 窗口,因此用户可以添加自己的评论。
在第一个小时左右的新安装中,一切都可以完美运行。如果用户通过 iOS 设置应用程序登录,他们会看到一个快速的 iOS 确认框,我得到他们的令牌,将其发送到我的服务器,我们都很好。
如果我将收到的令牌粘贴到 Facebook 的 Access Token 调试器中,它会显示它将在一小时后过期。
如果我等了那个小时然后回到应用程序,我尝试做的任何事情都会给我这个错误:
{"error_code":190,"
error_msg":"Error validating access token:
Session has expired at unix time 1351497600.
The current unix time is 1351525180. }
- 我需要做什么才能使事情正常进行?我在 SDK 3.1.1 中读过 FBSession 会处理它,但情况似乎并非如此。我的访问令牌即将到期,一旦到期,iOS/FB SDK 将不会给我一个更新的令牌。
- 即使注销(调用
[FBSession.activeSession closeAndClearTokenInformation]
)也无法解决此问题。我唯一能做的就是在 iOS 模拟器首选项中“重置内容和设置”,在 Settings.app 中重新输入我的 FB 凭据,然后重建我的应用程序。只有这样我才能获得另一个将在一小时内到期的令牌。
散记:
- 当我的应用程序恢复时,我正在
[FBSession.activeSession handleDidBecomeActive]
打电话[self.facebook extendAccessTokenIfNeeded]
- 根据上面链接的 SO 问题,SDK 应该会自动调用
FBSession#renewSystemAuthorization
. 我已经在其中放置了一个 NSLog,但我从未看到该方法被调用。
更新#1:
我提到我已经读过 SDK 将处理无效/过期的令牌。这似乎应该发生在 FBRequestConnection#completeWithResults:orError: 中。有关代码路径的注释,请参见内联注释。
- (void)completeWithResults:(NSArray *)results
orError:(NSError *)error
{
int count = [self.requests count];
for (int i = 0; i < count; i++) {
FBRequestMetadata *metadata = [self.requests objectAtIndex:i];
id result = error ? nil : [results objectAtIndex:i];
NSError *itemError = error ? error : [self errorFromResult:result];
id body = nil;
if (!itemError && [result isKindOfClass:[NSDictionary class]]) {
NSDictionary *resultDictionary = (NSDictionary *)result;
body = [FBGraphObject graphObjectWrappingDictionary:[resultDictionary objectForKey:@"body"]];
}
...
// *******************************************
// My code actually falls into this block, proving that I do in fact have an invalid session
// *******************************************
if ([self isInvalidSessionError:itemError
resultIndex:error == itemError ? i : 0]) {
[metadata.request.session closeAndClearTokenInformation:itemError];
// *******************************************
// Unfortunately metadata.request.session is nil, so this condition is never
// run, so renewySystemAuthorization is never called
// *******************************************
if (metadata.request.session.loginType == FBSessionLoginTypeSystemAccount){
[FBSession renewSystemAuthorization];
}
}
...
}