【问题标题】:Safari Services crash [SFAuthenticationViewController dismissViewControllerAnimated:completion:]Safari 服务崩溃 [SFAuthenticationViewController dismissViewControllerAnimated:completion:]
【发布时间】:2018-04-10 16:06:23
【问题描述】:

我的应用程序经常崩溃。 iOS 系统的崩溃似乎只发生在最新的 iOS 11 中。

这是崩溃

Crashed: com.apple.main-thread
0  libobjc.A.dylib                0x18439d7ec objc_object::release() + 8
1  SafariServices                 0x1995d471c __75-[SFAuthenticationViewController dismissViewControllerAnimated:completion:]_block_invoke + 32
2  UIKit                          0x18e5bf030 -[UIPresentationController transitionDidFinish:] + 1320
3  UIKit                          0x18e79e760 -[_UICurrentContextPresentationController transitionDidFinish:] + 44
4  UIKit                          0x18e5c2a20 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke_2 + 188
5  UIKit                          0x18e38e9d8 -[_UIViewControllerTransitionContext completeTransition:] + 116
6  UIKit                          0x18e38e7c8 -[UITransitionView notifyDidCompleteTransition:] + 252
7  UIKit                          0x18e38e260 -[UITransitionView _didCompleteTransition:] + 1128
8  UIKit                          0x18e38dde4 -[UITransitionView _transitionDidStop:finished:] + 120
9  UIKit                          0x18e2b370c -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 312
10 UIKit                          0x18e2b3418 -[UIViewAnimationState animationDidStop:finished:] + 296
11 UIKit                          0x18e2b34b8 -[UIViewAnimationState animationDidStop:finished:] + 456
12 QuartzCore                     0x188e57d6c CA::Layer::run_animation_callbacks(void*) + 284
13 libdispatch.dylib              0x1847f1048 _dispatch_client_callout + 16
14 libdispatch.dylib              0x1847fdb74 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1016
15 CoreFoundation                 0x184e13f20 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
16 CoreFoundation                 0x184e11afc __CFRunLoopRun + 2012
17 CoreFoundation                 0x184d322d8 CFRunLoopRunSpecific + 436
18 GraphicsServices               0x186bc3f84 GSEventRunModal + 100
19 UIKit                          0x18e2df880 UIApplicationMain + 208
20 Jaumo                          0x1005674b4 main (main.m:20)
21 libdyld.dylib                  0x18485656c start + 4

不确定这是什么崩溃。任何人都可以帮助解决这个问题?

【问题讨论】:

  • 我面临同样的问题。你找到解决办法了吗?
  • @Jelly 还没有,我还在等待帮助
  • 好的,我发现它就在我身边。也许它会帮助你。长话短说,登录被调用了两次,导致崩溃。
  • @Jelly 哦,真的吗??你的意思是 Facebook 登录对吗?
  • 是的,- (void)logInWithReadPermissions:(NSArray *)permissions fromViewController:(UIViewController *)fromViewController handler:(FBSDKLoginManagerRequestTokenHandler)handler

标签: ios crash ios11


【解决方案1】:

在我们更新到最新的 Facebook SDK(从相当旧的 4.11 到 4.27.1)后,我们遇到了同样的问题。实际上,我们从触发 Facebook 登录的 applicationDidBecomeActive 事件发起了一些调用(因此打开 SFAuthenticationSession 会打开 SFAuthenticationViewController 提示,要求用户继续使用 Facebook 或其他第 3 方进行身份验证)。一旦用户点击“继续”,它就会再次触发applicationDidBecomeActive 事件。这导致开始新的SFAuthenticaionSessions 的无限循环导致崩溃。所以我们决定根本不从这个事件中调用 Facebook 登录。总结一下如何避免这种崩溃:你必须确保你同时只调用一次 Facebook 登录(或SFAuthenticationSessionstart() 方法)。

【讨论】:

    【解决方案2】:

    正如@Zoltán Homoki 和@Jelly 所说,我们应该只给logInWithReadPermissions 打一次电话。

    为此,一个常见的实现(以前没问题)是在appDelegate 中设置一个标志,例如:

    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
    {
        if ([[url.scheme substringToIndex:2] isEqualToString:@"fb"]) {
            _fromFbConnect = YES; // <- This flag
            returnValue = [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
        }
        // Manage app deep links here
    }
    

    然后用它来防止多次调用Facebook登录:

    - (void)applicationDidBecomeActive:(UIApplication *)application
    {
        [FBSDKAppEvents activateApp];
    
        if (_fromFbConnect == NO) { // <- Always `YES` on iOS11 with FB SDK 4.27
            // Refresh the facebook token
            if ([FBSDKAccessToken currentAccessToken] != nil) {
                [[FBSDKLoginManager new] logInWithReadPermissions: // ...
            }
            _fromFbConnect = NO;
        }
    }
    

    问题是在 iOS11 上 FBSDKLoginKit >= 4.27 application:openURL:sourceApplication:annotation: 没有被调用(也没有application:openURL:option),所以没有设置标志。这会创建对登录名的多次调用(applicationDidBecomeActive 在用户关闭第一个弹出窗口时被调用)

    我找到的解决方案是在对 FBSDKLoginManager 的任何调用之前设置一个标志并停止任何其他调用,直到该过程完成。

    @property (assign, nonatomic) BOOL fbRequesting;
    
    // ...
    
    if(_fbRequesting == YES) {
        NSLog(@"Facebook login already in progress");
        return;
    }
    
    if ([FBSDKAccessToken currentAccessToken] != nil) {
        return;
    }
    
    _fbRequesting = YES;
    [FBSDKProfile enableUpdatesOnAccessTokenChange:YES];
    
    NSLog(@"Logging in to Facebook...");
    
    @weakify(self);
    [[FBSDKLoginManager new] logInWithReadPermissions:... fromViewController:... handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
        @strongify(self);
    
        // Handle login
    
        _fbRequesting = NO;
        })
    ];
    

    这似乎适用于 FBSDKLoginKit 的 4.22 至 4.28 版本。

    【讨论】:

    • 好收获!我要试试!
    • 我可以看到当您使用 Facebook 登录时调用了 openURL。
    • 嗯,对我来说问题的根源是可以以某种方式对logInWithReadPermissions 进行两次调用。我还把FBSDKLoginBehavior改回native(鉴于systemAccount在iOS11上是不可能的)
    • FBSDKLoginBehavior 应该没有任何区别,因为当操作系统不提供 systemAccount 时,FB SDK 应该自动回退到 native
    • @Manuel 我同意,它不应该有任何区别¯_(ツ)_/¯
    【解决方案3】:

    刚刚在 FB SDK 4.31.1 中遇到了这个崩溃,这就是我解决它的方法。

    在我的情况下,只有当我尝试开始登录 FB 时,当 FB 登录已经开始时才会发生崩溃(屏幕上有一个 Safari Web 视图)。

    所以我只是检查:

    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
    while (topController.presentedViewController) {
           topController = topController.presentedViewController;
        }
    
    if ([topController isKindOfClass:[MyViewController class]])
    {
         // If that's my view controller, we can start FB Login
    }
    

    【讨论】:

    • 另一种方法可以检查topViewController是否属于SFSafariViewController类,它是私有类SFAuthenticationViewController的父类。
    • 您应该在尝试使用 FB SDK 登录 FB 的地方使用此代码。 IE。您的登录代码应该在 topController 类型检查之后。
    猜你喜欢
    • 1970-01-01
    • 2012-12-22
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 2018-01-18
    • 2016-06-12
    • 2017-07-29
    相关资源
    最近更新 更多