ios - 与iOS应用程序集成的Facebook登录页面间歇性关闭

标签 ios objective-c facebook facebook-ios-sdk

我的是 Objective-C 中的 iOS 应用程序,并集成了用于登录功能的 Facebook SDK。

我有一个显示按钮的主视图 Controller 。单击按钮时,将在按钮处理程序上执行下面提到的代码。

    FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
    [login
     logInWithReadPermissions: @[@"public_profile", @"email"]
     fromViewController:self
     handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
         if (error) {
             NSLog(@"Process error %@",error.description);
         }
         else if (result.isCancelled) {
             NSLog(@"Cancelled");
         }
         else {
             if ([result.grantedPermissions containsObject:kEmail]) {
                 [self fetchfbUserInfo];
             }
             else {
                 NSLog(@"User Declined permissions");
             }
         }
     }];

当来自 Facebook 的登录页面显示在我们应用程序的 webview 中时,如果 Facebook 登录页面保持原样/无人看管一段时间,它会间歇性关闭,并在控制台中显示以下错误。

FBSDKLog: ERROR: The SFSafariViewController's parent view controller was dismissed. This can happen if you are triggering login from a UIAlertController. Instead, make sure your top most view controller will not be prematurely dismissed.

做了一些逆向工程,发现必须为错误消息调用 FBSDKApplicationDelegate 类 的委托(delegate)方法。

- (void)viewControllerDidDisappear:(FBSDKContainerViewController *)viewController animated:(BOOL)animated
{
  if (_safariViewController) {
    [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
                           logEntry:@"**ERROR**:\n The SFSafariViewController's parent view controller was dismissed.\n"
     "This can happen if you are triggering login from a UIAlertController. Instead, make sure your top most view "
     "controller will not be prematurely dismissed."];
    [self safariViewControllerDidFinish:_safariViewController];
  }
}

关于为什么登录页面(或应用程序授权页面,如果已经登录)自行关闭/关闭的任何可能原因?

最佳答案

自 iOS 9 以来,FB iOS SDK 中的默认行为是使用移动 Safari 对用户进行身份验证(与 native iOS FB 应用程序相反)。当用户尝试使用 Facebook 登录您的应用程序但从未在移动版 Safari 中登录过 Facebook(无 cookie)时,Safari 会加载一个页面,向用户提供“使用 Facebook 应用程序登录”。点击该按钮会将用户带到 FB native 应用程序,这会导致 Safari 页面被关闭(并且您的应用程序会移至后台)。这实际上取消登录流程并返回到FBSDKLoginManagerLoginResult。用 isCancelled == true block .

当用户在 native FB 应用程序中接受权限并返回您的应用程序时,application:openURL:options:fb<your-fb-app-id>:// 调用url(其中包含访问 token )。根据 FB SDK 登录指南,此 url 应传递给:

[[FBSDKApplicationDelegate sharedInstance] application:application openURL:url options:options];

但是FBSDKApplicationDelegate只是忽略 url 并返回 NO因为登录流程事先被“取消”了。

对我来说,这看起来像是 FB SDK 中的一个严重错误。

我发现这个问题的唯一解决方法是:

- (BOOL) application:(UIApplication*)application openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
    BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url options:options];
    if (!handled) {
        NSMutableDictionary *launchOptions = [NSMutableDictionary new];
        launchOptions[UIApplicationLaunchOptionsSourceApplicationKey] = options[UIApplicationOpenURLOptionsSourceApplicationKey];
        launchOptions[UIApplicationLaunchOptionsAnnotationKey] = options[UIApplicationOpenURLOptionsAnnotationKey];
        launchOptions[UIApplicationLaunchOptionsURLKey] = url;
        return [[FBSDKApplicationDelegate sharedInstance] application:application
                                 didFinishLaunchingWithOptions:launchOptions];
    }

    return handled;
}

上面实际上将访问 token 存储在 FB SDK 中。

为了继续您的登录流程,您可以观察 FBSDKAccessTokenDidChange通知,将在上面的 FB url 处理后调用。

关于ios - 与iOS应用程序集成的Facebook登录页面间歇性关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38659559/

相关文章:

iphone - Documents 目录中的读/写文件问题

objective-c - 突然无法读取该类型的文件

html - Facebook Feed Plugin 自适应高度

ios - iOS 延迟初始化

ios - iOS 没有这样的文件或目录

ios - 每次将新版本推送到应用商店时,如何防止用户事件激增

ios - 处理核心数据中未定义的键

Facebook 侧边栏/选项卡应用程序

ios - 处理 openURL : with Facebook and Google

使用 .p8 文件后未收到 iOS Firebase 云消息通知