Facebook登录对话框在iOS6模拟器上无法工作。

6

我一直在将我的应用程序从旧版Facebook SDK转换为新版Facebook SDK 3.1,以便使用iOS6本地功能以及其他Facebook功能。但是我遇到了一个问题,模拟器上会经常出现,设备上则很少出现。

当我尝试登录Facebook时,我的应用程序背景不再通过Safari或Facebook应用程序进行身份验证,而是出现了一个模态窗口来完成登录(我相信这始于iOS6,甚至在切换到Facebook SDK 3.0 / 3.1之前就开始发生)。这个窗口允许我输入用户名和密码,但当我点击右上角的"Okay"进行身份验证时,没有任何反应。在AppDelegate中的application: openURL:sourceApplication:annotation:回调函数中,应用程序并未收到任何返回值。

Facebook Login

在我共享的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,并且我已经设置了URL Schemes,其中fb###[url_scheme_suffix]也是如此。
我和Facebook示例代码之间唯一的区别是,我使用了URL方案后缀,因为我们的应用有免费和付费版本。
如果应用程序使用Safari登录,则根据给定的代码可以工作。如果它快速切换到Facebook应用程序,它也可以工作。此外,共享的Facebook iOS6帐户设置也有效。只有当应用程序使用应用内模态时才会失败。
有其他人遇到过这个问题吗?

你是否在你的应用程序和Facebook应用程序设置中都指定了Bundle ID? - Shireesh Asthana
Bundle ID是在Facebook应用程序设置中设置的(实际上有两个设置,因为我们有两个应用程序版本),而Bundle标识符则在应用程序plist中设置。 - Peter Nolen
请确认您在 -initWithAppID:permissions... 方法中是否真的提供了 nil 作为应用程序 ID。 - Kristofer Sommestad
在初始化Facebook时,在Facebook应用程序中传递是正确的。我刚刚检查过它,它不是nil。 - Peter Nolen
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文件中配置的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),并且没有对源代码进行任何进一步的更改。
通过这些更改,fb登录过程按预期工作。
希望这能有所帮助!

你是否已经向Facebook提交了拉取请求或错误报告? - yonix
不,我没有开启错误报告。如果你想的话,可以随意这样做。 - Lio

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