Safari服务崩溃[SFAuthenticationViewController dismissViewControllerAnimated:completion:]

18

我的应用程序经常崩溃。看起来是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
@Jelly 哦,真的吗?你是指Facebook登录对吧? - Pablo Martinez
是的,- (void)logInWithReadPermissions:(NSArray *)permissions fromViewController:(UIViewController *)fromViewController handler:(FBSDKLoginManagerRequestTokenHandler)handler - Jelly
问题似乎只出现在sdk >=4.27上。暂时降级也可能解决它。 - Jelly
显示剩余6条评论
3个回答

3
我们在更新到最新的Facebook SDK(从相当旧的版本4.11到4.27.1)之后遇到了相同的问题。实际上,我们有一些从applicationDidBecomeActive事件开始的调用,这触发了Facebook登录(因此打开了一个SFAuthenticationSession,它会打开SFAuthenticationViewController,提示用户继续使用Facebook或其他第三方进行身份验证)。一旦用户点击“继续”,它就会再次触发applicationDidBecomeActive事件。这导致了不断启动新的SFAuthenticaionSessions,从而导致崩溃。因此,我们决定根本不从此事件调用Facebook登录。总结如何避免此崩溃:您必须确保您在同一时间只调用一次Facebook登录(或SFAuthenticationSession start()方法)。

2

我刚刚在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的父类。 - Manuel
你应该在尝试使用FB SDK登录FB时使用这段代码。也就是说,在检查 topController 类型之后,您的登录代码应该放在其后面。 - Torello

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。

好的发现!我会尝试的! - Pablo Martinez
当您使用Facebook登录时,我可以看到openURL被调用。 - Pablo Martinez
嗯,对我来说问题的根源是logInWithReadPermissions可能会被调用两次。而且,我将FBSDKLoginBehavior更改回“native”(考虑到iOS 11上不可能使用“systemAccount”)。 - Axel Guilmin
由于FB SDK在操作系统无法提供“systemAccount”时会自动回退到“native”,因此“FBSDKLoginBehavior”不应该有任何影响。 - Manuel
@Manuel 我同意,这不应该有任何影响 ¯_(ツ)_/¯ - Axel Guilmin

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