react-native-webrtc / react-native-webrtc/react-native-callkeep
iOS App terminated by Watchdog (Signal 9) in Background state despite reporting call
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.1k
- Forks
- 511
- Avg merge
- 9h 12m
- Merged PRs (30d)
- 2
Description
Title: iOS App terminated by Watchdog (Signal 9) in Background state despite reporting call
Description
I have successfully implemented VoIP pushes for the Killed state, where CallKit triggers correctly. However, when the app is in the Background state (suspended), it consistently crashes with an NSInternalInconsistencyException.
The app process is killed by the iOS Watchdog because it fails to satisfy the requirement of posting an incoming call in the same run loop as the push receipt, or the completion handler is not being released fast enough by the JS bridge.
Environment
- React Native Version: .78
- React Native CallKeep Version: 4.3.14
- React Native VoIP Push Notification Version: 3.3.3
- iOS Version: 18.x
- Device: Physical iPhone [iphone 13 pro]
The Issue
When a VoIP push arrives while the app is in the Background:
pushRegistry:didReceiveIncomingPushWithPayload:is called.RNCallKeep.reportNewIncomingCallis triggered on the Main Thread.- The app is terminated by the system before the CallKit UI is fully established or before the
completion()closure is executed.
Current Implementation (AppDelegate.swift)
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
let payloadDict = payload.dictionaryPayload
let callerName = payloadDict["callerName"] as? String ?? "Unknown Caller"
let callUUIDString = payloadDict["uuid"] as? String ?? UUID().uuidString
let userGUID = payloadDict["guid"] as? String ?? "0"
RNCallKeep.reportNewIncomingCall(
callUUIDString,
handle: userGUID,
handleType: "generic",
hasVideo: false,
localizedCallerName: callerName,
supportsHolding: true,
supportsDTMF: true,
supportsGrouping: true,
supportsUngrouping: true,
fromPushKit: true,
payload: ["userGuid": userGUID],
withCompletionHandler: {
}
)
RNVoipPushNotificationManager.didReceiveIncomingPush(with: payload, forType: type.rawValue)
completion()
}
Logs
Exception Type: EXC_CRASH (SIGKILL)
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: TCC 1 |
[CoreFoundation] Killing app because it never posted an incoming call to the system after receiving a PushKit VoIP push.
Observed Behavior
- Killed State: Works perfectly.
- Foreground State: Works perfectly.
- Background State: The phone may vibrate once, but the app process is killed before the CallKit UI appears.
Questions/Suspected Causes
- Is
RNVoipPushNotificationManager.addCompletionHandlercausing a delay in the background run loop that triggers the Watchdog? - Should
completion()be called immediately in Swift for the Background state, rather than waiting forVoipPushNotification.onVoipNotificationCompletedin JS? - Is there a known issue with
RNCallKeepnot being able to present the UI while the app is in a suspended background state?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in AppDelegate.swift at pushRegistry(_:didReceiveIncomingPushWith:for:completion:), then trace RNCallKeep.reportNewIncomingCall and RNVoipPushNotificationManager.didReceiveIncomingPush. Reproduce a VoIP push while the app is suspended on a physical iPhone and compare when the completion handlers execute. Done means the background push posts the incoming call without the watchdog terminating the process.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, react-native, swift
- Domain
- audio-video-rtc, mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100