6

我一直在将我的应用程序从旧的 Facebook SDK 转换为新的 Facebook SDK 3.1,以便使用 iOS6 原生功能以及其他 Facebook 功能,但我遇到了一个在模拟器上始终如一且很少在设备上发生的问题。

当我登录 Facebook 时,不是通过 Safari 或 Facebook 应用程序进行后台和身份验证,而是在我的应用程序顶部获得一个用于登录的模式窗口(我相信这始于 iOS6,甚至在切换到 Facebook SDK 3.0 之前/3.1)。这个窗口允许我输入用户名和密码,但是当我点击右上角的“确定”进行身份验证时,什么也没有发生。AppDelegate 中的 application:openURL:sourceApplication:annotation: 不会发生回调。

Facebook登入

在我共享的 FacebookController 代码(我用于多个项目)中,我在尝试根据 Facebook 的示例代码进行授权时初始化 FBSession:

FBSession *session = [[FBSession alloc] initWithAppID:nil permissions:readPermissions defaultAudience:FBSessionDefaultAudienceNone urlSchemeSuffix:self.fbUrlSchemeSuffix tokenCacheStrategy:nil];

if(session.state == FBSessionStateCreated || session.state == FBSessionStateCreatedTokenLoaded)
{
  [FBSession setActiveSession:session];

  // we open after the fact, in order to avoid overlapping close
  // and open handler calls for blocks
  [session openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
...

除非我单击对话框上的 x 取消按钮,否则永远不会执行完成处理程序的代码(在这种情况下,我会收到预期的错误)。

我在我的 iOS 目标属性 (info.plist) 中设置 FacebookAppID,并且我还使用 fb###[url_scheme_suffix] 设置了 URL 方案。

我的代码和 Facebook 示例代码之间的唯一区别是我使用的是 url 方案后缀,因为我有我们的应用程序的免费和付费版本。

如果应用程序使用 Safari 登录,它将使用给定的代码。如果它快速切换到 Facebook 应用程序,它也可以工作。此外,共享的 facebook ios6 帐户设置工作。该应用仅在使用应用内模式时才会失败。

有人遇到过这种情况么?

4

1 回答 1

1

同样的事情也发生在我身上。它只发生在模拟器上(iphone5 4英寸,ios6),所以我不知道这个问题是否会出现在实际设备中。

经过几次调试会话后,我发现 FBDialog 的 webView:shouldStartLoadWithRequest:navigationType: 方法没有处理带有 access_token 的 url。当 facebook 通过 access_token 时,这意味着您已通过身份验证。所以,我想,那里缺少一些东西。

这是未处理的 url 的形状:

fb122222222222222 ://authorize/# access_token =...& expires_in =5102464& code =...

请注意,url 方案与您在应用程序的 Info.plist 文件中配置的 fb+API 密钥相同。

这是我为解决此问题所做的。请注意,我添加了一个新的 else-if 分支,如果我们有访问令牌,我会在其中调用对话成功:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
 navigationType:(UIWebViewNavigationType)navigationType {
    NSURL* url = request.URL;

    if ([url.scheme isEqualToString:@"fbconnect"]) {
        if ([[url.resourceSpecifier substringToIndex:8] isEqualToString:@"//cancel"]) {
            NSString * errorCode = [self getStringFromUrl:[url absoluteString] needle:@"error_code="];
            NSString * errorStr = [self getStringFromUrl:[url absoluteString] needle:@"error_msg="];
            if (errorCode) {
                NSDictionary * errorData = [NSDictionary dictionaryWithObject:errorStr forKey:@"error_msg"];
                NSError * error = [NSError errorWithDomain:@"facebookErrDomain"
                                                      code:[errorCode intValue]
                                                  userInfo:errorData];
                [self dismissWithError:error animated:YES];
            } else {
                [self dialogDidCancel:url];
            }
        } else {
            if (_frictionlessSettings.enabled) {
                [self dialogSuccessHandleFrictionlessResponses:url];
            }
            [self dialogDidSucceed:url];
        }
        return NO;
    }
//THIS IS WHAT I'VE ADDED>>>>
        else if ([[[[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleURLTypes"] firstObject] objectForKey:@"CFBundleURLSchemes"] firstObject] isEqual:url.scheme])
        {
            [self dialogDidSucceed:url];
            return NO;
        }
//<<<<<
    else if ([_loadingURL isEqual:url]) {
        return YES;
    } else if (navigationType == UIWebViewNavigationTypeLinkClicked) {
        if ([_delegate respondsToSelector:@selector(dialog:shouldOpenURLInExternalBrowser:)]) {
            if (![_delegate dialog:self shouldOpenURLInExternalBrowser:url]) {
                return NO;
            }
        }

        [[UIApplication sharedApplication] openURL:request.URL];
        return NO;
    } else {
        return YES;
    }
}

值得一提的是,我正在遵循所有 fb sdk 指南(3.1),并且我没有对 src 代码进行任何进一步的更改。

通过这些更改,fb 登录过程按预期工作。

我希望这有帮助!

于 2012-10-23T13:27:52.353 回答