Display the system-calling UI for your app’s VoIP services and coordinate your calling services with other apps and the system using CallKit.

Posts under CallKit tag

125 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

iOS Phone app bug: Long verdict text incorrectly truncated on call details screen
I've discovered a bug in the Phone app on iOS related to how long verdicts are displayed. When a call is identified by a third-party Caller ID app, long verdicts display correctly during the call (they auto-scroll) and in the call log (with an ellipsis at the end). However, on the call details screen, the text is strangely truncated - showing only the beginning of the string and the last word. For testing, I used this verdict: "Musclemen grow on trees. They can tense their muscles and look good in a mirror. So what? I'm interested in practical strength that's going to help me run, jump, twist, punch." I'll attach a screenshots demonstrating the problem:
0
0
41
3h
CXCallUpdate not working for outgoing calls
I try to update remoteHandle using CXCallUpdate for outgoing call, but this works only on iOS 15 but not on 17 or 18 (16 didn't test). This problem actual only for outgoing calls, but for incoming calls update works fine. func startOutgoingCall(with callID: UUID, userID: String) { let handle = CXHandle(type: .generic, value: userID) let action = CXStartCallAction(call: callID, handle: handle) callController.requestTransaction(with: action) { [weak self] error in // ... } } func updateOutgoingCall(with callID: UUID, groupID: String) { let update = CXCallUpdate() update.remoteHandle = CXHandle(type: .generic, value: groupID) provider.reportCall(with: callID, updated: update) } I also tried phoneNumber type but it seems initial handle that I set to CXStartCallAction not possible to change (value or even type). I use this handle value to implement recall by tap on call in Recents tab of system address book. But since my calls can transform from p2p to group call, I need to update handle value or find some another way to pass call identification info.
0
0
99
23h
Live Caller ID Lookup & PIRService blocking inconsistent
I've successfully started the Live Caller ID Lookup example and initialized the PIRService. I added several identities to the input.txtpb file, some with block: true and others with block: false. Here is the file but modified phone digits: identities { key: "+40790123123" value { name: "Blocking 1" cache_expiry_minutes: 7 block: true } } identities { key: "+972526111111" value { name: "Blocking 2" cache_expiry_minutes: 7 block: true } } identities { key: "+123" value { name: "Adam" cache_expiry_minutes: 8 block: false category: IDENTITY_CATEGORY_PERSON } } identities { key: "+972526111112" value { name: "Identified Business Name 1" cache_expiry_minutes: 1 block: false category: IDENTITY_CATEGORY_BUSINESS } } identities { key: "+972526111113" value { name: "Identified Business Name 2" cache_expiry_minutes: 1 block: false category: IDENTITY_CATEGORY_BUSINESS } } The main issue is that only the number marked as +40790123123 was actually blocked, while "Blocking 2" appeared as identified contacts with their assigned name displayed. Notably, the only blocked number was a foreign number with a different country code than the number being called. The other numbers belonged to the same country. Can someone clarify whether this is a bug in the example project or an issue with the data file?
1
0
99
23h
APNS is delivering expired voip push notification.
I have tried setting a 'apns-expiration' to current time + 30 seconds and also a value '0'. But still my voip app receives the voip push notification after 2-3 minutes. Till this time, caller has already hung up the call. But the receivers phone still rings on receiving the push notification as we have to report it to CallKit. Am I missing something or there is no way and even 'apns-expiration' does not guarantee timely delivery of Voip push notifications or discard if it is expired. I have set 'apns-priority' to 10 already as recommended.
1
0
154
19h
Behavior of CallKit with multiple incoming calls
Hi, Team. We are currently creating a VoIP calling app using pjsip and want to be able to handle 4 calls at the same time. It is also necessary to be able to notice calls that are on hold or have not answered yet in hands-free (without looking the screen). However, It seems like CallKit has the intention to silence the ringtone when multiple calls come in. Problem What does actually happen? If a second call comes in while the first one have not answered yet, CallKit screen keeps showing about the first one. If tapped "Accept" button, the second call ends. If tapped "Decline" button, CallKit screen shows about the second call at last. If the first call has put on hold before the second one comes in, CallKit screen shows "Hold & Accept" button even though the first call is already on hold. When "Hold & Accept" button is displayed, ringtones and other sounds from app stop. When tapped "Hold & Accept" button for the second call and then unhold the first one in provider(_ provider: CXProvider, perform action: CXAnswerCallAction), ringtone of the first call doesn't ring. What is expected to happen? If a second call comes in while the first one have not answered yet, CallKit screen shows about the second call. If tapped "Accept" button, the second call starts and the first call is displayed on CallKit screen. If tapped "Decline" button, the first call appears again. If the first call has put on hold before the second one comes in, CallKit screen shows only "Accept" and "Decline" button (not in full screen). If a second call comes in while the first one have not answered yet, ringtones continue to ring. When accepted the second call, ringtone of the first call rings again. Information Sample code Using CallKit to simulate three incoming calls and two alarm notifications. Whether or not the first call is put on hold before the second one comes in is switchable from the bottom menu. https://github.com/ryu-akaike/CallKit-Multiple-Incoming-Test Versions macOS: Sequoia 15.1 Xcode: 16.2 iPhone: 11 iOS: 18.1.1 Thank you. Ryu Akaike
0
0
66
2d
How can a live caller id database be scaled to support millions of numbers that constantly change if it must be KPIR encoded?
The example database/server provided by Apple for Live Caller ID contains a hardcoded database with a tiny number of pre-defined numbers. However, its not expected to be representational of an live real world usage server. But the question is how can that be accomplished if its a requirement that the data be KPIR encrypted? In real world scenarios, the factors that effect whether a number should be blocked or not are continually changing and evolving on a minute-by-minute basis and new information becomes available or existing information changes. If the database supports tens of millions or hundreds of millions of constantly changing phone numbers, in order to meet the requirements of the Live Caller ID being KPIR encrypted, that would imply the database has to re-encrypt its database of millions endlessly for all time. That seems unfeasable and impractical to implement. Therefore how do the Apple designers of this feature envisage/suggest a real-world server supporting millions of changing data should meet the requirement to be KPIR encrypted?
0
0
243
5d
iOS Blocking Websocket Reconnection After Multiple VoIP Push Notifications
Hello, We have a Push-to-Talk (PTT) application that is already well established and widely used. Our app has the proper VoIP entitlement, which we are using to wake up the app and establish a WebSocket connection for real-time communication. We are also using CallKit as a supporting mechanism, but not as the primary interaction upon receiving the VoIP Push, since our use case differs from traditional full-duplex VoIP calls. While our implementation works correctly in many cases, we have noticed a consistent issue where, after multiple VoIP Push notifications, the system still delivers the push, but prevents the WebSocket from reconnecting. At this point, all connection attempts return errors such as: • "Software caused connection abort" This issue persists until the app is manually relaunched, after which the behavior resets and repeats. We are aware that VoIP Push was originally designed for full-duplex calls, but since Apple allows its use for other purposes through the entitlement, we would like to understand why this limitation is occurring and how to handle it properly. Questions: 1. Is iOS enforcing stricter background execution rules after multiple VoIP Push events within a short period? 2. Are there any recommended best practices to ensure reliable WebSocket reconnection in this scenario?
0
6
218
1w
Issue with app not waking up intermittently due to Pushkit (VOIP)
I am developing a VoIP service. Usually, when receiving a VoIP Push, Callkit is exposed immediately after receiving the message and the app is designed to be used. However, there is an extremely intermittent phenomenon (not well reproduced) where the app does not wake up even when receiving a VoIP Push. And after a long time, the app wakes up and Callkit is activated. (A long time after receiving the call…) Has anyone experienced the above phenomenon? I wonder if there are any reported parts depending on the OS version. (I have identified that it does not occur in the 17.x version, but it is difficult to guarantee because it occurs extremely intermittently) The app is not running in the background, but... Could this be happening if there are a lot of pending operations in the background? I need help urgently
4
0
219
4d
Live Caller ID: Multiple userIdentifier values for same device - Expected behavior?
Hello! We're currently testing Live Caller ID implementation and noticed an issue with userIdentifier values in our database. Initially, we expected to have approximately 100 records (one per user), but the database grew to about 10,000 evaluationKey entries. Upon investigation, we discovered that the userIdentifier (extracted from "User-Identifier" header) for the same device remains constant throughout a day but changes after a few days. We store these evaluation keys using a composite key pattern "userIdentifier/configHash". All these entries have the same configHash but different userIdentifier values. This behavior leads to unnecessary database growth as new entries are created for the same users with different userIdentifier values. Could you please clarify: Is this the expected behavior for userIdentifier to change over time? If yes, is there a specific TTL (time-to-live) for userIdentifier? If this is not intended, could this be a potential iOS bug? This information would help us optimize our database storage and implement proper cleanup procedures. Thank you for your assistance!
4
1
264
1d
VoIP Push Notification Not Received in Background/Killed State
I am implementing flutter_callkit_incoming for handling call notifications in my Flutter app. However, I am facing an issue where VoIP push notifications are not consistently received when the app is in the background or terminated. According to Apple’s documentation: "On iOS 13.0 and later, if you fail to report a call to CallKit, the system will terminate your app. Repeatedly failing to report calls may cause the system to stop delivering any more VoIP push notifications to your app." I have followed the official installation guide: flutter_callkit_incoming installation and implemented all necessary configurations. However, VoIP notifications sometimes get lost and do not deliver reliably. Here is the payload I am using: { "notification": { "title": "New Alert", "body": "@H is calling you..." }, "android": { "notification": { "channelId": "channel_id", "sound": "sound_name.mp3" } }, "apns": { "payload": { "aps": {} } }, "data": { "title": "New Call", "body": "@H is calling you...", "notificationType": "CALL", "type": "NOTIFICATION", "sound": "sound_name" }, "token": "token" } I expect the call notification to appear even when the app is in the background or killed state. Has anyone encountered this issue and found a solution? Any insights would be greatly appreciated.
1
0
189
1w
LiveCommunicationKit: report Incoming but Assertion failure in -[PKPushRegistry _terminateAppIfThereAreUnhandledVoIPPushes]
I completed the CallKit Demo with the same code. When I changed to LiveCommunicationKit, the code goes perfectly when the app is in foreground, but it crashed in background. If I changed the reportIncoming method from LCK to CallKit, it goes well. What is the reason? I changed the method from func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) to func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) async it crashed before show the print "receive voip noti". Here is the core code: var providerDelegate: ProviderDelegate? func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) { if type != .voIP { return } guard let uuidString = payload.dictionaryPayload["uuid"] as? String, let uuid = UUID(uuidString: uuidString), let handle = payload.dictionaryPayload["handle"] as? String, let hasVideo = payload.dictionaryPayload["hasVideo"] as? Bool, let callerID = payload.dictionaryPayload["callerID"] as? String else { return } print("receive voip noti: \(type):\(payload.dictionaryPayload)") if #available(iOS 17.4, *) { // This code is only goes perfectly when the App is in foreground var update = Conversation.Update(members: [Handle(type: .generic, value: callerID, displayName: callerID)]) if hasVideo { update.capabilities = [.video, .playingTones] } else { update.capabilities = .playingTones } Task { @MainActor in do { print("LCKit report start") try await LCKitManager.shared.reportNewIncomingConversation(uuid: uuid, update: update) print("LCKit report success") completion() } catch { print("LCKit report failed") print(error) completion() } } } else { // It went perfectly providerDelegate?.reportIncomingCall(uuid: uuid, callerID: callerID, handle: handle, hasVideo: hasVideo) { _ in completion() } } @available(iOS 17.4, *) final class LCKitManager { static let shared = LCKitManager() let manager: ConversationManager init() { manager = ConversationManager(configuration: type(of: self).configuration) manager.delegate = self } static var configuration: ConversationManager.Configuration { ConversationManager.Configuration(ringtoneName: "Ringtone.aif", iconTemplateImageData: #imageLiteral(resourceName: "IconMask").pngData(), maximumConversationGroups: 1, maximumConversationsPerConversationGroup: 1, includesConversationInRecents: true, supportsVideo: false, supportedHandleTypes: [.generic]) } func reportNewIncomingConversation(uuid: UUID, update: Conversation.Update) async throws { try await manager.reportNewIncomingConversation(uuid: uuid, update: update) } } final class ProviderDelegate: NSObject, ObservableObject { static let providerConfiguration: CXProviderConfiguration = { let providerConfiguration: CXProviderConfiguration if #available(iOS 14.0, *) { providerConfiguration = CXProviderConfiguration() } else { providerConfiguration = CXProviderConfiguration(localizedName: "Name") } providerConfiguration.supportsVideo = false providerConfiguration.maximumCallGroups = 1 providerConfiguration.maximumCallsPerCallGroup = 1 let iconMaskImage = #imageLiteral(resourceName: "IconMask") providerConfiguration.iconTemplateImageData = iconMaskImage.pngData() providerConfiguration.ringtoneSound = "Ringtone.aif" providerConfiguration.includesCallsInRecents = true providerConfiguration.supportedHandleTypes = [.generic] return providerConfiguration }() private let provider: CXProvider init( { provider = CXProvider(configuration: type(of: self).providerConfiguration) super.init() provider.setDelegate(self, queue: nil) } func reportCall(uuid: UUID, callerID: String, handle: String, hasVideo: Bool, completion: ((Error?) -> Void)? = nil) { let callerUUID = UUID() let update = CXCallUpdate() update.remoteHandle = CXHandle(type: .generic, value: callerID) update.hasVideo = hasVideo update.localizedCallerName = callerID // Report the incoming call to the system provider.reportNewIncomingCall(with: callerUUID, update: update) { [weak self] error in completion?(error) } } }
18
0
654
4d
How to Get Incoming Call Notifications to Create a Phone App in iOS 18.2+?
I am trying to create a phone app that can receive incoming call notifications using CallKit, as described in Apple's CallKit documentation. Added the com.apple.developer.calling-app entitlement in my .entitlements file. Implemented CXProvider and set up the delegate methods (provider:perform: and providerDidReset). Added UIBackgroundModes with voip in Info.plist. Configured CXProviderConfiguration to support phone numbers. I expected to receive incoming call notifications when my app was set as the default calling app. However, I am not receiving any notifications when an incoming call arrives. How can I properly detect and handle incoming calls in my default calling app? Is there any additional configuration required for iOS 18.2+?
0
0
183
2w
Implement webrtc voice calls in the background
I am developing an App that will enable voice calls between users through webrtc. When the user opens the App and switches the App to the background, the user will receive the incoming call notification through Silent Push Notifications (not PushKit). My question is as follows, If set UIBackgroundModes to voip and do not use PushKit and CallKit, will this cause the background App to be unable to use webrtc voice calls (requires network, microphone, and audio permissions)? Can I set UIBackgroundModes = audio combined with AVAudioSession playAndRecord instead of setting UIBackgroundModes to voip, so that I can use the microphone and audio in the background to implement webrtc voice calls? Thanks for your help.
1
0
304
2w
When Using Callkit audio doesn't have permission to work
I am creating a voip app, I am trying to use call kit to answer calls, however audio doesn't seem to work when using callKit when looking at the systems logs I see no server connection when checking background audio state, won't allow background audio! background audio processAllowed = 0 for displayID com.apple.TelephonyUtilities no server connection when checking background audio state, won't allow background audio! background audio processAllowed = 0 for displayID {my app id} I have the plist entries for background ui modes for voip, audio, fetch and background notifications along with the backgrounds modes for Voip, Audio, AirPlay, and Picture in Picture, Background notifications. I am unsure what to do about this, like my reading of the error is I can't use audio cause I am not connected to a server, but like is it any server, Am I suppose to connect to the voip call before setting up audio, I am not sure how to do that.
1
0
177
2w
Using Flutter with CallKit
When using CallKit in my flutter app audio(both mic and speaker) stop working. When not using call kit to answer calls the app work fine. I am using the flutter flutter_callkit_incoming to use callkit and flutter_webrtc for the telephony. Flutter_callkit_incoming has some boilerplate code code include sections to uncomment when using webrtc and I have seen multiple fixes to suggest to make sure the to configure sharedAudioSession before the callkit is sent. Neither of this approaches seemed to have worked.
2
0
228
3w
Under certain conditions, using CallKit does not automatically enable the microphone.
Issue: Under certain conditions, using CallKit does not automatically enable the microphone. Steps to Reproduce: 1.Start an outgoing call, then the user manually mutes the audio. 2.Receive a native incoming call, end the current call, then answer the new incoming call.(This order is important.) 3.End the incoming call. 4.Start another outgoing call and observe the microphone; do not manually mute or unmute. Actual Behavior: The audio icon indicates that the audio is unmuted, but the microphone remains off, and the small yellow dot in the top status bar (which represents the microphone) does not appear. Expected Behavior: The microphone should be on, consistent with the audio icon display, and the small yellow dot should appear in the top status bar. Device: iPhone 16 pro & iPhone 15 pro, iOS 18.0+ Can it be reproduced using speakerbox(CallKit Demo)? YES
2
1
306
4d
Firebase Notification Fails to Dismiss Voip CallKit UI in Background & Terminated Mode
Hi everyone, I am developing a VoIP calling feature in my Flutter app, using: Agora RTC Engine for real-time calls. CallKit & PushKit (VoIP notifications) for iOS call handling. Firebase Cloud Messaging (FCM) for notifications. Problem: CallKit UI Stays on Screen When Caller Hangs Up (Background/Terminated) I am using Firebase notifications to notify the receiver that the call should be dismissed, but it doesn’t work in the following cases: App is in the background – CallKit UI remains stuck even after receiving the Firebase notification. App is terminated – The Firebase notification does not trigger any background execution, so CallKit UI stays forever. Current Implementation I send an FCM notification to inform the receiver to dismiss CallKit UI. When received in the foreground, it works fine (callEnded method is triggered). But in background or terminated state, the notification is not received or doesn’t execute the code.
1
0
242
4w