Safari 服务崩溃 [SFAuthenticationViewController dismissViewControllerAnimated:completion:]
Safari Services crash [SFAuthenticationViewController dismissViewControllerAnimated:completion:]
我的应用经常崩溃。似乎 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
不确定这是什么崩溃。有人可以帮助解决这个问题吗?
更新到最新的 Facebook SDK(从相当旧的版本 4.11 到 4.27.1)后,我们遇到了同样的问题。实际上,我们有一些调用是从触发 Facebook 登录的 applicationDidBecomeActive
事件发起的(因此打开 SFAuthenticationSession
会打开 SFAuthenticationViewController
提示,要求用户继续通过 Facebook 或其他第 3 方进行身份验证).用户点击 "Continue" 后,它会再次触发 applicationDidBecomeActive
事件。这导致开始新 SFAuthenticaionSessions
的无限循环导致崩溃。所以我们决定根本不从这个事件中调用 Facebook 登录。总结一下如何避免这种崩溃:您必须确保同时只调用一次 Facebook 登录(或 SFAuthenticationSession
start()
方法)。
正如@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 版本。
刚遇到 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
}
我的应用经常崩溃。似乎 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
不确定这是什么崩溃。有人可以帮助解决这个问题吗?
更新到最新的 Facebook SDK(从相当旧的版本 4.11 到 4.27.1)后,我们遇到了同样的问题。实际上,我们有一些调用是从触发 Facebook 登录的 applicationDidBecomeActive
事件发起的(因此打开 SFAuthenticationSession
会打开 SFAuthenticationViewController
提示,要求用户继续通过 Facebook 或其他第 3 方进行身份验证).用户点击 "Continue" 后,它会再次触发 applicationDidBecomeActive
事件。这导致开始新 SFAuthenticaionSessions
的无限循环导致崩溃。所以我们决定根本不从这个事件中调用 Facebook 登录。总结一下如何避免这种崩溃:您必须确保同时只调用一次 Facebook 登录(或 SFAuthenticationSession
start()
方法)。
正如@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 版本。
刚遇到 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
}