It is rather rare to reproduce and explain bugs
Some users have remote logs for calls.
Log for iOS 26.2.1 & identifier iPhone18,2
To understand:
there is no inital providerDidBegin for first CXProvider as logger misses early logs
if our logic triggers CXProvider invalidation so Provider to invalidate nil
if iOS triggers CXProvider invalidation so Provider to invalidate Optional(<CXXPCProvider: ...>)
func invalidateProvider(..) invalidates provider when either nil or equal to current provider
second call providerDidReset happens after invalidateProvider as delagate is not set to nil
Pls keep an eye on CXProvider 0x10e0463c0. A very first one
12:45:33_473-730:[CallsProviderDelegate.swift:47 -- providerDidReset(:)] providerDidReset <CXXPCProvider: 0x10e0463c0>
12:45:33_478-738:[CallsController.swift:307 -- invalidateProvider(:)] Provider to invalidate Optional(<CXXPCProvider: 0x10e0463c0>)
12:45:33_478-739:[CallsController.swift:308 -- invalidateProvider(:)] Current provider <CXXPCProvider: 0x10e0463c0>
12:45:33_488-742:[CallsProviderDelegate.swift:47 -- providerDidReset(:)] providerDidReset <CXXPCProvider: 0x10e0463c0>
12:45:33_495-754:[CallsProviderDelegate.swift:61 -- providerDidBegin(:)] DidBegin: <CXXPCProvider: 0x1261f3680>
12:45:33_497-755:[CallsProviderDelegate.swift:61 -- providerDidBegin(:)] DidBegin: <CXXPCProvider: 0x10e0463c0>
providerDidBegin is fired for for 0x10e0463c0
Here happens strange thing*
14:25:41_743-3257:[CallsController.swift:307 -- invalidateProvider(:)] Provider to invalidate nil
14:25:41_743-3258:[CallsController.swift:308 -- invalidateProvider(:)] Current provider <CXXPCProvider: 0x1261f3680>
14:25:41_744-3261:[CallsProviderDelegate.swift:47 -- providerDidReset(:)] providerDidReset <CXXPCProvider: 0x1261f3680>
14:25:41_749-3286:[CallsProviderDelegate.swift:61 -- providerDidBegin(:)] DidBegin: <CXXPCProvider: 0x1259d5fc0>
14:25:49_363-3362:[CallsController.swift:307 -- invalidateProvider(:)] Provider to invalidate nil
14:25:49_363-3363:[CallsController.swift:308 -- invalidateProvider(:)] Current provider <CXXPCProvider: 0x1259d5fc0>
14:25:49_365-3367:[CallsProviderDelegate.swift:47 -- providerDidReset(:)] providerDidReset <CXXPCProvider: 0x1259d5fc0>
14:25:49_369-3389:[CallsController.swift:307 -- invalidateProvider(:)] Provider to invalidate Optional(<CXXPCProvider: 0x1259d5fc0>)
14:25:49_369-3390:[CallsController.swift:308 -- invalidateProvider(:)] Current provider <CXXPCProvider: 0x1259d6480>
14:25:49_372-3393:[CallsProviderDelegate.swift:61 -- providerDidBegin(:)] DidBegin: <CXXPCProvider: 0x1259d6480>
14:26:33_094-3504:[CallsController.swift:307 -- invalidateProvider(:)] Provider to invalidate nil
14:26:33_094-3505:[CallsController.swift:308 -- invalidateProvider(:)] Current provider <CXXPCProvider: 0x1259d6480>
14:26:33_097-3511:[CallsProviderDelegate.swift:47 -- providerDidReset(:)] providerDidReset <CXXPCProvider: 0x1259d6480>
14:26:33_104-3535:[CallsProviderDelegate.swift:61 -- providerDidBegin(:)] DidBegin: <CXXPCProvider: 0x1259d5800>
17:09:47_668-4911:[CallsProviderDelegate.swift:47 -- providerDidReset(:)] providerDidReset <CXXPCProvider: 0x1259d5800>
17:09:47_676-4920:[CallsController.swift:307 -- invalidateProvider(:)] Provider to invalidate Optional(<CXXPCProvider: 0x1259d5800>)
17:09:47_676-4921:[CallsController.swift:308 -- invalidateProvider(:)] Current provider <CXXPCProvider: 0x1259d5800>
17:09:47_691-4925:[CallsProviderDelegate.swift:47 -- providerDidReset(:)] providerDidReset <CXXPCProvider: 0x10e0463c0>
17:09:47_691-4933:[CallsController.swift:307 -- invalidateProvider(:)] Provider to invalidate Optional(<CXXPCProvider: 0x10e0463c0>)
17:09:47_691-4934:[CallsController.swift:308 -- invalidateProvider(:)] Current provider <CXXPCProvider: 0x1258eab00>
17:09:47_698-4937:[CallsProviderDelegate.swift:47 -- providerDidReset(:)] providerDidReset <CXXPCProvider: 0x1259d5800>
17:09:47_699-4945:[CallsController.swift:307 -- invalidateProvider(:)] Provider to invalidate Optional(<CXXPCProvider: 0x1259d5800>)
17:09:47_699-4946:[CallsController.swift:308 -- invalidateProvider(:)] Current provider <CXXPCProvider: 0x1258eab00>
17:09:47_701-4949:[CallsProviderDelegate.swift:61 -- providerDidBegin(:)] DidBegin: <CXXPCProvider: 0x1258eab00>
0x10e0463c0 is still alive
19:44:21_051-5641:[CallsProviderDelegate.swift:47 -- providerDidReset(:)] providerDidReset <CXXPCProvider: 0x1258eab00>
19:44:21_059-5650:[CallsController.swift:307 -- invalidateProvider(:)] Provider to invalidate Optional(<CXXPCProvider: 0x1258eab00>)
19:44:21_059-5651:[CallsController.swift:308 -- invalidateProvider(:)] Current provider <CXXPCProvider: 0x1258eab00>
19:44:21_068-5655:[CallsProviderDelegate.swift:47 -- providerDidReset(:)] providerDidReset <CXXPCProvider: 0x10e0463c0>
19:44:21_069-5663:[CallsController.swift:307 -- invalidateProvider(:)] Provider to invalidate Optional(<CXXPCProvider: 0x10e0463c0>)
19:44:21_069-5664:[CallsController.swift:308 -- invalidateProvider(:)] Current provider <CXXPCProvider: 0x124e34240>
19:44:21_085-5667:[CallsProviderDelegate.swift:47 -- providerDidReset(:)] providerDidReset <CXXPCProvider: 0x1258eab00>
19:44:21_091-5675:[CallsController.swift:307 -- invalidateProvider(:)] Provider to invalidate Optional(<CXXPCProvider: 0x1258eab00>)
19:44:21_091-5676:[CallsController.swift:308 -- invalidateProvider(:)] Current provider <CXXPCProvider: 0x124e34240>
19:44:21_104-5679:[CallsProviderDelegate.swift:61 -- providerDidBegin(:)] DidBegin: <CXXPCProvider: 0x124e34240>
0x10e0463c0 is still alive
A very strange place* has log:
14:13:19_554-3215:[CallsController.swift:599 -- set(call:ended:)] Report call ended, reason: CXCallEndedReason(rawValue: 2)
Code
Logs show that CallKit didn't end it. Code fails to register new calls. Tries to reset CXProvider. While logs have line:
14:25:41_744-3264:[CallsProviderDelegate.swift:50 -- providerDidReset(_:)] ☎️ providerDidReset calls count 1
Count is
For all above:
Such hard destiny for 0x10e0463c0 is observed first time. May be it is iOS bug. You can refer to retain cycles on our side but other providers seem to be retained/released properly. But may be any other explanations?
Logic to end call in CallKit is based on reason. If reason then use reportCall(with, endedAt, reason:) otherwise CXEndCallAction is used. Strange pattern is observed not first time. iOS calls providerDidReset for a first CXProvider. And after a few calls func reportCall(with UUID: UUID, endedAt dateEnded: Date?, reason endedReason: CXCallEndedReason) does NOT end call.call.UUID is proper. Would be nice to read any explanation.