与iOS应用程序

时间:2016-07-29 12:59:12

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

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

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

    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:错误:SFSafariViewController的父视图   控制员被解雇了。如果您正在触发登录,则会发生这种情况   来自UIAlertController。相反,请确保您的最顶层视图   控制器不会过早被解雇。

进行了一些逆向工程并发现必须为错误消息调用 FBSDKApplicationDelegate类的委托方法。

- (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];
  }
}

登录页面(或登录后的应用程序授权页面)为何会关闭/解散其自身的任何可能原因?

1 个答案:

答案 0 :(得分:2)

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

当用户接受本机FB应用中的权限并返回到您的应用时,将使用application:openURL:options: url(包含访问令牌)调用fb<your-fb-app-id>://。根据FB SDK登录指南,此URL应传递给:

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

但是FBSDKApplicationDelegate只是忽略了网址并返回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;
}

以上实际上将访问令牌存储在FB SDK中。

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