【发布时间】:2019-03-23 13:43:49
【问题描述】:
自 2017 年 11 月起,我在 AppStore 中提供了一个 iOS (swift) 应用程序。我添加了 Firebase Analytics 和 Crashlytics 以主动查看在开发和测试期间未发生的问题。
我目前正在为以下 Stacktrace 苦苦挣扎,我在 Firebase Crashlytics Dashboard 中多次遇到该问题:
来自 Firebase 的 Stacktrace
致命异常:NSInternalInconsistencyException 这个请求有 已绝育 - 您不能调用 -sendResponse: 两次,也不能在编码后调用 它
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x1ac20bef8 __exceptionPreprocess
1 libobjc.A.dylib 0x1ab3d9a40 objc_exception_throw
2 CoreFoundation 0x1ac12006c +[_CFXNotificationTokenRegistration keyCallbacks]
3 Foundation 0x1acc0c3e0 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
4 BaseBoard 0x1aea6cd68 __40-[BSAction sendResponse:withCompletion:]_block_invoke
5 libdispatch.dylib 0x1abc44484 _dispatch_client_callout
6 libdispatch.dylib 0x1abc24754 _dispatch_lane_barrier_sync_invoke_and_complete
7 BaseBoard 0x1aea20c60 -[BSAction sendResponse:withCompletion:]
8 UIKitCore 0x1d8c20698 -[UIHandleRemoteNotificationAction sendResponse:]
9 UIKitCore 0x1d9054d3c __91-[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion:]_block_invoke_3.2891
10 libdispatch.dylib 0x1abc436c8 _dispatch_call_block_and_release
11 libdispatch.dylib 0x1abc44484 _dispatch_client_callout
12 libdispatch.dylib 0x1abc23b44 _dispatch_main_queue_callback_4CF$VARIANT$armv81
13 CoreFoundation 0x1ac19a1bc __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
14 CoreFoundation 0x1ac195084 __CFRunLoopRun
15 CoreFoundation 0x1ac1945b8 CFRunLoopRunSpecific
16 GraphicsServices 0x1ae408584 GSEventRunModal
17 UIKitCore 0x1d903cbc8 UIApplicationMain
18 <APP-NAME> 0x10251bc84 main (AppDelegate.swift:18)
19 libdyld.dylib 0x1abc54b94 start
奇怪的是,在开发和测试过程中,根本没有出现这个特定的错误。
我最近几天就这个话题做了很多研究。我发现了几个 SO 帖子,这个问题已经解决了。
iOS 8 NSInternalInconsistencyException
Unable to understand where MyApp is crashing
基本上,当您调用completionHandler 两次时,就会发生崩溃。但在不同的帖子中,他们指的是两种不同的方法,但两者都有相同的completionHandler:
执行FetchWitchCompletionHandler
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// code here
completionHandler(.newData)
}
didReceiveRemoteNotification
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// code here
completionHandler(.newData)
}
我找不到两次调用这两种方法的 completionHandler 的位置。我的问题是,是否可以在 AppDelegate 中实现这两种方法而不会出现上述错误。或者performFetchWitchCompletionHandler和didReceiveRemoteNotification这两种方法并行实现会不会互相干扰?
【问题讨论】:
-
你能分享一下编译处理程序中的代码
-
完成处理程序中的代码在我们的例子中并不重要,因为我每个函数只有一次。我的问题是这两种方法是否相互干扰或更明确的方向 - 这两种方法的完成处理程序是否相互干扰,因为我仍然得到提到的错误
-
您的堆栈跟踪与我的匹配,错误和您的评论帮助我使用 UIHandleRemoteNotificationAction 缩小了搜索范围。我查看了 AppDelegate 的 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void),发现 completionHandler 被调用了两次。当用户点击触发应用启动的推送通知(消息)时,我确信这就是我崩溃的原因。
-
@dferrero 我的应用程序也有同样的问题。你能解决这个问题吗?如果有,怎么做?
-
@naqi - 在我的例子中,我有一个 for 循环,在我调用完成处理程序的地方执行了多次。一旦我在循环中调用了完成处理程序,我就手动退出了循环。但是在我的情况下,如果我的应用程序即将终止,我还有另一个侦听器,它会被额外调用。
标签: ios swift completionhandler background-fetch