We have also been seeing this. We are unable to reproduce locally, but we have crash reports coming in that look the same, all on iOS 14, and we had a few on iOS 13.6 starting on about July 21st. The crashes have different stack traces, but all have the same tell tale failure reason. We have evidence of it working fine for a customer for 8 different consecutive calls sent via push, and on the ninth call, it failed the moment the push was sent to APNS from our backend.
We are also doing exactly what was required in iOS 13, reporting directly to CallKit the incoming call from the receipt of the push event. We have a minimal little bit of processing time to get the push event and get it ready for callkit (we have some validations and decryption, etc) but it directly gets to callkit in a synchronous flow. The stack traces show us failing about half way along this processing time. Depending on where it stops it, we get a different stack trace. We are both in the foreground and background.
Post
Replies
Boosts
Views
Activity
While digging deeper it seems to me to be a threading issue.... I have a stack trace that shows:
Thread 16 name:
Thread 16:
0	 libsystem_kernel.dylib				 0x00000001ad963504 kevent_id + 8
1	 libdispatch.dylib						 0x00000001ad80aff4 _dispatch_kq_poll + 228 (event_kevent.c:750)
2	 libdispatch.dylib						 0x00000001ad80ba94 _dispatch_event_loop_wait_for_ownership$VARIANT$armv81 + 436 (event_kevent.c:2203)
3	 libdispatch.dylib						 0x00000001ad801388 DISPATCH_WAIT_FOR_QUEUE + 312 (queue.c:1657)
4	 libdispatch.dylib						 0x00000001ad800f90 _dispatch_sync_f_slow + 140 (queue.c:1738)
5	 PushKit											 0x00000001c3f2c624 -[PKPushRegistry _noteIncomingCallReported] + 76 (PKPushRegistry.m:360)
6	 CoreFoundation								 0x00000001adac0cf8 CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER + 20 (CFNotificationCenter.c:706)
7	 CoreFoundation								 0x00000001adac0cb8 ___CFXRegistrationPost_block_invoke + 48 (CFNotificationCenter.c:173)
8	 CoreFoundation								 0x00000001adac02b0 _CFXRegistrationPost + 400 (CFNotificationCenter.c:198)
9	 CoreFoundation								 0x00000001adabfca8 _CFXNotificationPost + 696 (CFNotificationCenter.c:1071)
10	Foundation										 0x00000001ade6aa00 -[NSNotificationCenter postNotificationName:object:userInfo:] + 60 (NSNotification.m:575)
11	CallKit											 0x00000001bd8bd708 -[CXProvider reportNewIncomingCallWithUUID:update:completion:] + 160 (CXProvider.m:221)
<10-20 redacted>
21	PushKit											 0x00000001c3f2b554 __73-[PKPushRegistry voipPayloadReceived:mustPostCall:withCompletionHandler:]_block_invoke + 400 (PKPushRegistry.m:175)
22	libdispatch.dylib						 0x00000001ad81d298 _dispatch_call_block_and_release + 24 (init.c:1454)
23	libdispatch.dylib						 0x00000001ad81e280 _dispatch_client_callout + 16 (object.m:559)
24	libdispatch.dylib						 0x00000001ad7fa4fc _dispatch_lane_serial_drain$VARIANT$armv81 + 568 (inline_internal.h:2548)
25	libdispatch.dylib						 0x00000001ad7fafe8 _dispatch_lane_invoke$VARIANT$armv81 + 404 (queue.c:3862)
26	libdispatch.dylib						 0x00000001ad804808 _dispatch_workloop_worker_thread + 692 (queue.c:6590)
27	libsystem_pthread.dylib			 0x00000001ad8755a4 _pthread_wqthread + 272 (pthread.c:2194)
28	libsystem_pthread.dylib			 0x00000001ad878874 start_wqthread + 8
Which clearly is showing the push event calling the reportIncoming to the CXProvider, which then post a notification to the notification center which is picked up by the PKPushRegistry, noting that the incoming call was acknoledged. but at the same time on a different thread i have this:
Last Exception Backtrace:
0	 CoreFoundation								 0x1adb5dea8 __exceptionPreprocess + 216 (NSException.m:199)
1	 libobjc.A.dylib							 0x1ad880f48 objc_exception_throw + 56 (objc-exception.mm:565)
2	 CoreFoundation								 0x1ada6d064 +[NSException raise:format:arguments:] + 96 (NSException.m:146)
3	 Foundation										 0x1adedbfc8 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 128 (NSException.m:231)
4	 PushKit											 0x1c3f2c5b4 -[PKPushRegistry _terminateAppIfThereAreUnhandledVoIPPushes] + 208 (PKPushRegistry.m:353)
5	 libdispatch.dylib						 0x1ad81e280 _dispatch_client_callout + 16 (object.m:559)
6	 libdispatch.dylib						 0x1ad7f6c04 _dispatch_continuation_pop$VARIANT$armv81 + 404 (inline_internal.h:2548)
7	 libdispatch.dylib						 0x1ad807474 _dispatch_source_invoke$VARIANT$armv81 + 1252 (source.c:570)
8	 libdispatch.dylib						 0x1ad7fa3c8 _dispatch_lane_serial_drain$VARIANT$armv81 + 260 (inline_internal.h:2589)
9	 libdispatch.dylib						 0x1ad7fafe8 _dispatch_lane_invoke$VARIANT$armv81 + 404 (queue.c:3862)
10	libdispatch.dylib						 0x1ad804808 _dispatch_workloop_worker_thread + 692 (queue.c:6590)
11	libsystem_pthread.dylib			 0x1ad8755a4 _pthread_wqthread + 272 (pthread.c:2194)
12	libsystem_pthread.dylib			 0x1ad878874 start_wqthread + 8
which makes me think that the handling of checking if we are in a acknowledged state seems to not be thread safe, or there is some timer that has a super short fuse that is detonating even if the call was acknowleged.
Basically something to the effect of this would show the AVRoutePicker's view and hide it behind a custom button. the AVRoutePicker button was available in iOS 13, and before that we used the MPVolumeView to do about the same. There is no direct way to select the routes, only show the system UI to show the view.
var button: UIButton?
var picker: AVRoutePickerView = AVRoutePickerView()
var detector: AVRouteDetector = AVRouteDetector()
detector.isRouteDetectionEnabled = true
addSubview(picker)
picker.frame = CGRect.zero
picker.isHidden = true
button = picker.subviews.filter({$0 is UIButton}).first as? UIButton
button?.sendActions(for: .touchUpInside)