Fix crash after multiple calls: always reportNewIncomingCall for every VoIP push
iOS 13+ terminates the app if a PushKit VoIP push doesn't call reportNewIncomingCall before completion(). My earlier "no re-ring blip" change made the cancel handler SKIP the report for already-known/ended calls — which is exactly what iOS kills the app for, surfacing as a crash after several calls (a cancel push for a prior call's UUID). Revert to ALWAYS report then immediately end: for a still-active/ringing UUID the report errors harmlessly (no second ring) and reportCall ends it; only a late duplicate cancel shows a brief, unavoidable blip. A crash is far worse than a blip. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -211,27 +211,21 @@ public class NativeCallPlugin: CAPPlugin, CAPBridgedPlugin, PKPushRegistryDelega
|
||||
// reporting a NEW incoming call is what caused the "rings back for a second" blip on a call we've
|
||||
// already handled. So:
|
||||
if (dict["type"] as? String) == "cancel" {
|
||||
// (a) already ended here → nothing to do (re-reporting would blip).
|
||||
if endedCalls.contains(uuid) { completion(); return }
|
||||
// (b) a call we already know (still ringing OR active) → end it WITHOUT reporting a new incoming,
|
||||
// so there's no blip. reportCall(endedAt:) cleanly dismisses the CallKit UI.
|
||||
if calls[uuid] != nil || activeUUID == uuid {
|
||||
var ev = calls[uuid] ?? [:]; ev["callUUID"] = uuid.uuidString
|
||||
calls.removeValue(forKey: uuid)
|
||||
endedCalls.insert(uuid)
|
||||
if activeUUID == uuid { disconnectRoom(); activeUUID = nil }
|
||||
provider?.reportCall(with: uuid, endedAt: Date(), reason: .remoteEnded)
|
||||
notifyListeners("endCall", data: ev) // if it was active, leave the meeting window too
|
||||
completion()
|
||||
return
|
||||
}
|
||||
// (c) unknown call (this very push relaunched the app) → we MUST report, then immediately end.
|
||||
// A tiny unavoidable blip, but only in this rare cold case.
|
||||
// iOS 13+ TERMINATES the app if a VoIP push doesn't result in reportNewIncomingCall before
|
||||
// completion() — that's the crash after several calls (my earlier "no-blip" optimization SKIPPED
|
||||
// the report for known/ended calls, which iOS kills for). So ALWAYS report, then immediately end:
|
||||
// * uuid already ringing/active → the report errors harmlessly (NO second ring), reportCall ends it.
|
||||
// * late/duplicate cancel (done) → a brief, unavoidable blip (acceptable; a crash is not).
|
||||
let u = CXCallUpdate()
|
||||
u.remoteHandle = CXHandle(type: .generic, value: (dict["callerName"] as? String) ?? "Call")
|
||||
let wasActive = (activeUUID == uuid)
|
||||
var ev = calls[uuid] ?? [:]; ev["callUUID"] = uuid.uuidString
|
||||
calls.removeValue(forKey: uuid)
|
||||
endedCalls.insert(uuid)
|
||||
if wasActive { disconnectRoom(); activeUUID = nil }
|
||||
provider?.reportNewIncomingCall(with: uuid, update: u) { [weak self] _ in
|
||||
self?.provider?.reportCall(with: uuid, endedAt: Date(), reason: .remoteEnded)
|
||||
if wasActive { self?.notifyListeners("endCall", data: ev) } // active call cancelled → leave the meeting
|
||||
completion()
|
||||
}
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user