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

200 Posts

Post

Replies

Boosts

Views

Activity

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
2
0
386
Mar ’25
Incoming call notifications problems
Good day We developed a simple swift code to make the device ringing when a certain type of notifications arrives from our backend. This is the code: let phoneNumber = CXHandle(type: .generic, value: (self.userInfoForPluginCall!["data"] as! [String:Any]) ["caller"] as! String) callUpdate.remoteHandle = phoneNumber let configuration = CXProviderConfiguration(localizedName: "Trec Conf") configuration.maximumCallGroups = 1 configuration.maximumCallsPerCallGroup = 1 configuration.supportsVideo = false configuration.supportedHandleTypes = [.generic] configuration.iconTemplateImageData = UIImage(named: "callkit-icon")?.pngData() let callProvider = CXProvider(configuration: configuration) callProvider.setDelegate(self, queue: nil) callProvider.reportNewIncomingCall(with: callUUID!, update: callUpdate, completion: {error in}) We are noticing some problems on the call screen: on certain devices (iOS 18.4RC) the normal call screen appears and the user can answer or decline the call, on other devices (iOS 18.3, especially with dynamic island) only a phone icon appears in the upper right corner and no possibility to answer or deny call. Any idea on why we are encountering that behavior? Thanks
0
0
193
Mar ’25
Call Tracking with CallKit Works in Debug Mode but Not in Release (TestFlight) – iOS
I am working on an iOS app using Flutter that tracks outgoing calls using CallKit. The call tracking functionality works perfectly in Debug mode but does not work when the app is published to TestFlight. I have already added Background Modes (voip, audio, processing, fetch) in Info.plist. I have added CallKit.framework in Xcode under Link Binary With Libraries (set to Optional). <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>aps-environment</key> <string>production</string> </dict> </plist> These are the necessary permission which I used in info.plist: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>BGTaskSchedulerPermittedIdentifiers</key> <array> <string>com.agent.mygenie</string> </array> <key>CADisableMinimumFrameDurationOnPhone</key> <true/> <key>CFBundleDevelopmentRegion</key> <string>$(DEVELOPMENT_LANGUAGE)</string> <key>CFBundleDisplayName</key> <string>MyGenie</string> <key>CFBundleDocumentTypes</key> <array/> <key>CFBundleExecutable</key> <string>$(EXECUTABLE_NAME)</string> <key>CFBundleIdentifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>mygenie</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>$(FLUTTER_BUILD_NAME)</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>$(FLUTTER_BUILD_NUMBER)</string> <key>LSRequiresIPhoneOS</key> <true/> <key>NSCallKitUsageDescription</key> <string>This app needs access to CallKit for call handling</string> <key>NSContactsUsageDescription</key> <string>This app needs access to your contacts for calls</string> <key>NSMicrophoneUsageDescription</key> <string>This app needs access to microphone for calls</string> <key>NSPhotoLibraryUsageDescription</key> <string>This app needs access to photo library for profile picture updation</string> <key>UIApplicationSupportsIndirectInputEvents</key> <true/> <key>UIBackgroundModes</key> <array> <string>voip</string> <string>processing</string> <string>fetch</string> <string>audio</string> </array> <key>UILaunchStoryboardName</key> <string>LaunchScreen</string> <key>UIMainStoryboardFile</key> <string>Main</string> <key>UISupportedInterfaceOrientations</key> <array> <string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array> <key>UISupportedInterfaceOrientations~ipad</key> <array> <string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortraitUpsideDown</string> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array> [code.txt](https://developer.apple.com/forums/content/attachment/0a327dbd-652e-41d5-8811-c462d09e0567) </dict> </plist> And below is the file are AppDelegate.swift, call_tracking_mixin.dart, & main_call.dart file for full knowledge
0
0
145
Mar ’25
Push Notification don't wake up my app
Hi everyone, We're experiencing an issue with our Flutter app that uses PushKit, CallKit, and Janus for handling VoIP calls. Everything works fine when the app is in the foreground, but when the app is in the background or completely closed (terminated state), the behavior is inconsistent: Sometimes, incoming calls are received as expected. Other times, the app does nothing, and the call is not delivered at all. Upon checking the console logs, we noticed that our app is being canceled (terminated by the system), which seems to be the reason why calls are not coming through. This happens randomly, making it difficult to reproduce consistently. Additional Details: The app is configured to handle VoIP notifications correctly. We are using PushKit to wake up the app and trigger CallKit for the incoming call UI. When the app is active, calls are handled correctly via Janus WebRTC signaling. We have verified that background modes for VoIP are enabled in the Info.plist. We suspect that iOS may be aggressively killing the app in the background, preventing incoming call notifications from reaching it. Questions: Has anyone experienced similar behavior with PushKit + CallKit on recent iOS versions? Could iOS be terminating the app due to background execution policies? Are there recommended best practices to ensure reliable delivery of VoIP notifications when the app is closed? Any insights or suggestions would be greatly appreciated! Thanks! Addional Information: this is the cancellation information at console: Received incoming message on topic hiperme.app at priority 10 por omisión 17:10:18.462084-0300 dasd CANCELED: com.apple.pushLaunch.hiperme.app:E8BACD at priority 10
0
0
177
Mar ’25
NSUserActivity in application(_:continue:restorationHandler:) not recognized as INStartCallIntent
Hello, experts! I'm working on a VOIP application that handles audio calls and integrates with CallKit. The problem occurs when attempting to redial a previously made audio call from the system's call history. When I try to handle the NSUserActivity in the application(_:continue:restorationHandler:) method, it intercepts the INStartAudioCallIntent instead of the expected INStartCallIntent. Background Deprecation Warnings: I'm encountering deprecation warnings when using INStartAudioCallIntent and INStartVideoCallIntent: 'INStartAudioCallIntent' was deprecated in iOS 13.0: INStartAudioCallIntent is deprecated. Please adopt INStartCallIntent instead. 'INStartVideoCallIntent' was deprecated in iOS 13.0: INStartVideoCallIntent is deprecated. Please adopt INStartCallIntent instead. As a result, I need to migrate to INStartCallIntent instead, but the issue is that when trying to redial a call from the system’s call history, INStartAudioCallIntent is still being triggered. Working with Deprecated Intents: If I use INStartAudioCallIntent or INStartVideoCallIntent, everything works as expected, but I want to adopt INStartCallIntent to align with the current iOS recommendations. Configuration: CXProvider Configuration: The CXProvider is configured as follows: let configuration = CXProviderConfiguration() configuration.supportsVideo = true configuration.maximumCallsPerCallGroup = 1 configuration.maximumCallGroups = 1 configuration.supportedHandleTypes = [.generic] configuration.iconTemplateImageData = UIImage(asset: .callKitLogo)?.pngData() let provider = CXProvider(configuration: configuration) Outgoing Call Handle: When making an outgoing call, the CXHandle is created like this: let handle = CXHandle(type: .generic, value: callId) Info.plist Configuration: In the info.plist, the following key is defined: &lt;key&gt;NSUserActivityTypes&lt;/key&gt; &lt;array&gt; &lt;string&gt;INStartCallIntent&lt;/string&gt; &lt;/array&gt; Problem: When trying to redial the audio call from the system's call history, the NSUserActivity received in the application(_:continue:restorationHandler:) method is an instance of INStartAudioCallIntent instead of INStartCallIntent. This happens even though INStartCallIntent is listed in NSUserActivityTypes in the info.plist and I want to migrate to the newer intent as recommended in iOS 13+. Device: iPhone 13 mini iOS version 17.6.1
0
1
271
Mar ’25
Push Notification
Hello. We're developing an app with Flutter that receives VoIP calls. However, when the app is in the background or closed, the push notification arrives, but the call doesn't. It works perfectly when the app is open. We use Firebase, Flutter, and JANUS WebRTC. We need to know what type of permissions or actions we should consider so that the app opens when it receives a call. How can we resolve this issue? Thank you very much.
0
0
145
Mar ’25
About 0xBAADCA11 error
I am developing "local push" VoIP application. I have a question about issues I found while testing this app. After repeating a test for 24 hours in which a incoming call followed by an immediate disconnect 0.1 seconds later, the iPhone of incommig call side encountered a 0xBAADCA11 error, causing iOS to force-close the app. (The incidence is low, occurring three times in 17280 times incoming call(24 hours.)) This problem found on iOS17.6.1 (iPhone11Pro). When the same test was performed on iOS18.2 (iPhoneSE3), the problem did not occur. Did iOS take something measures against the 0xBAADCA11 error between iOS17.6.1 and iOS18.2? If yes, I want to encourage customers to upgrade to the latest iOS version, please tell me about it? ※I have attached an ips files and sysdiagnose file of the 0xBAADCA11 error occurring. (please refer sysdiagnose also if you need.) FjSoftPhone-2025-01-16-113049.ips FjSoftPhone-2025-01-16-175253.ips FjSoftPhone-2025-01-17-070449.ips [sysdiagnose_2025.01.17_14-24-48+0900_iPhone-OS_iPhone_21G93.tar.gz] https://drive.google.com/file/d/1CV8laKzdnQxvwaAIOwMcXL8rAYL2jq35/view?usp=sharing
4
0
1.1k
Mar ’25
VOIP is not receiving calls
Hello, I am developing a calling service using CallKit and VOIP push. I have occasionally encountered a strange issue. The issue is that VOIP permanently fails to receive calls. I was previously informed that even if the device is blocked, it can receive calls again after 24 hours. Also, when I checked the device logic, it complied with the policy requirements set by Apple, including correctly calling CallKit's reportNewIncomingCall method. Once the issue occurs, no matter how many times I try, VOIP does not receive calls, and neither a device reboot nor checking the Device Console Log shows any logs related to CallKit or VOIP. I suspect this might be an issue with the VOIP token, and I believe that the only way to get a new one is to reinstall the app. Is that correct? Of course, after reinstalling, it works fine again, but this is very inconvenient. I don't think this is the right solution. Is there anyone who can share their insights on this issue? Thank you.
0
0
265
Mar ’25
Getting VoIP notifications to work and use iOS call UI when phone is locked/app is in background/Not running
Hey there my application allows users to have video calls with each other using Agora. I have successfully set up incoming call functionality on Android but on iOS I am struggling to get the call ui to appear when the app is not running/in background/locked. To my knowledge this is because there is much stricter security on iOS which is limiting me from calling this. When i initially set it up it worked at first when the app was in the background but I think I was failing to report the call to call kit in time and now it's not working. I'm not sure if I need access to this entitlement: com.apple.developer.pushkit.unrestricted-voip Which i believe is only for the big boys or if I make sure I'm reporting the call to call kit fast enough that I won't encounter this issue and it will consistently work in the background.
0
0
251
Mar ’25
Using `com.apple.developer.usernotifications.filtering` for developement
Ref: https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.usernotifications.filtering?language=objc Currently, it seems impossible to enable this entitlement for local development and testing without first going through Apple’s approval process. I would like to be able to test how it works on a side project without having to submit the form which seems designed for real app. There is any trick I can use?
1
0
277
Mar ’25
how can i get the LiveCommunicationKit events
i have codes looks like: import UIKit import LiveCommunicationKit @available(iOS 17.4, *) class LiveCallKit: NSObject, ConversationManagerDelegate { @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, conversationChanged conversation: Conversation) { } @available(iOS 17.4, *) func conversationManagerDidBegin(_ manager: ConversationManager) { } @available(iOS 17.4, *) func conversationManagerDidReset(_ manager: ConversationManager) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, perform action: ConversationAction) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, timedOutPerforming action: ConversationAction) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, didActivate audioSession: AVAudioSession) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, didDeactivate audioSession: AVAudioSession) { } @objc public enum InterfaceKind : Int, Sendable, Codable, Hashable { /// 拒绝/挂断 case reject /// 接听. case answer } var sessoin: ConversationManager var callId: UUID var completionHandler: ((_ actionType: InterfaceKind,_ payload: [AnyHashable : Any]) -&gt; Void)? var payload: [AnyHashable : Any]? @objc init(icon: UIImage!) { let data:Data = icon.pngData()!; let cfg: ConversationManager.Configuration = ConversationManager.Configuration(ringtoneName: "ring.mp3", iconTemplateImageData: data, maximumConversationGroups: 1, maximumConversationsPerConversationGroup: 1, includesConversationInRecents: false, supportsVideo: false, supportedHandleTypes: Set([Handle.Kind.generic])) self.sessoin = ConversationManager(configuration: cfg) self.callId = UUID() super.init() self.sessoin.delegate = self } @objc func toIncoming(_ payload: [AnyHashable : Any], displayName: String,actBlock: @escaping(_ actionType: InterfaceKind,_ payload: [AnyHashable : Any])-&gt;Void) async { self.completionHandler = actBlock do { self.payload = payload self.callId = UUID() var update = Conversation.Update(members: [Handle(type: .generic, value: displayName, displayName: displayName)]) let actNumber = Handle(type: .generic, value: displayName, displayName: displayName) update.activeRemoteMembers = Set([actNumber]) update.localMember = Handle(type: .generic, value: displayName, displayName: displayName); update.capabilities = [ .playingTones ]; try await self.sessoin.reportNewIncomingConversation(uuid: self.callId, update: update) try await Task.sleep(nanoseconds: 2000000000); } catch { } } } i want to listen the button event,but i can't find the solutions!please give me a code demo
0
0
233
Mar ’25
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
337
Mar ’25
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
387
Mar ’25
Live Caller ID on iOS does not work - client requests not reaching backend
I'm reaching out to see if anyone else is experiencing issues with the Live Caller ID feature on iOS. We recently encountered a problem where the feature stopped working entirely. Here's a brief overview of the situation: We were monitoring test traffic on our backend and noticed everything came to a halt around 1:00 AM UTC on November 15th. After this time, any attempts to reach our backend through calls failed completely. I tested this across multiple devices running iOS 18.2 and iOS 18.0. I used both TestFlight builds and development builds via Xcode, which should communicate directly with our backend. I experienced the problem on our main application as well as a dedicated test app. To troubleshoot further, I even set up a local server on localhost and tried directing requests there, but the requests did not reach the local server when a call was received. Further debugging in Console.app revealed the following error: identity request returned error: Error Domain=com.apple.CipherML Code=400 "Error Domain=com.apple.CipherML Code=401 "Unable to request data by keywords batch: failed to fetch token issuer directory" However, when I manually tried to hit our server endpoint using curl, the request successfully reached the server: curl https://our_server/something hb_method=GET hb_uri=/something [Hummingbird] Request -- log on backend This suggests that while our backend is responsive, the requests from the iOS client side are simply not being initiated.
9
3
1.6k
Mar ’25
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.
3
0
675
Mar ’25
CallKit outgoing calls UI
i thought it is impossible to have CallKit show system UI for outgoing calls. but then i saw this: "For incoming and outgoing calls, CallKit displays the same interfaces as the Phone app..." https://developer.apple.com/documentation/callkit how do i present it though? or is this a documentation error?
2
1
1.3k
Mar ’25
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
535
Mar ’25
Is it possible for a Live Caller ID server to specify different datasets?
In the documentation for the example Live Caller ID server (https://swiftpackageindex.com/apple/live-caller-id-lookup-example/main/documentation/pirservice/testinginstructions) there is an example service-config.json. file shown (without thorough documentation). That config file, and the whole of the instructions, center around there being two datasets of numbers: block and identity. My question is - is it possible for more than one dataset to be specified i.e. for block1 and block2 to be specified? The use case for this would be - suppose the Live Caller ID server has a set of numbers it has identified as being nuisance callers and so it lists these in the block section. However user A might want all these nuisance callers to be blocked but user B does not. Therefore the Live Caller ID extension on the handset would need to use a different dataset on the server so that user A's calls from a set of numbers is blocked, but user B's are not. Note that I'm not suggesting that the Caller ID server should be capable of storing individual user's preferences. All that would be required would be two data sets: one where blocked content is none and and one where blocked content is some. Then a user/app could switch between them as indicated by the user. Is that possible? If the database structure and service-config.json etc. is not configured to permit that, then could two different servers be set up to achieve this instead? i.e. so the server url specified in the app's extension can be set at run time and not at compile time?
5
0
1k
Mar ’25
Can a Live Caller ID server supply live data or must it be static?
With the Live Caller ID example server, the caller lookup dataset is defined in an input.txtpd and processed by running a ConstructDatabase command which creates a block.binpb and an identity.binpb file. In other words, a static input file is being processed into static block and identity files. However, in the real world, the data content for identified and blocked numbers is something which is in a constant state of flux and evolution, as new numbers becoming available, old ones become stale, numbers which were initially considered safe change into being considered malicious etc. etc. Is the example server just that, merely an example using fixed datasets, and an actual production server is able to use live every changing data to formulate its response back to the iPhone OS query? Here's a concrete use case - suppose it's a requirement to permit US nanp numbers but to block anything else. The total number of non US nanp numbers is so large and ever changing that it would be unfeasible to attempt to capture them in an input.txtpd file and then process that, and then to re-capture and re-process it endlessly. Instead what would be required is the ability for the Live Caller ID server to evaluate at query time, using a regular expressions for example, if a number is nanp or not. Is this possible?
5
1
933
Mar ’25
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 &amp; Accept" button even though the first call is already on hold. When "Hold &amp; Accept" button is displayed, ringtones and other sounds from app stop. When tapped "Hold &amp; 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
Replies
2
Boosts
0
Views
386
Activity
Mar ’25
Incoming call notifications problems
Good day We developed a simple swift code to make the device ringing when a certain type of notifications arrives from our backend. This is the code: let phoneNumber = CXHandle(type: .generic, value: (self.userInfoForPluginCall!["data"] as! [String:Any]) ["caller"] as! String) callUpdate.remoteHandle = phoneNumber let configuration = CXProviderConfiguration(localizedName: "Trec Conf") configuration.maximumCallGroups = 1 configuration.maximumCallsPerCallGroup = 1 configuration.supportsVideo = false configuration.supportedHandleTypes = [.generic] configuration.iconTemplateImageData = UIImage(named: "callkit-icon")?.pngData() let callProvider = CXProvider(configuration: configuration) callProvider.setDelegate(self, queue: nil) callProvider.reportNewIncomingCall(with: callUUID!, update: callUpdate, completion: {error in}) We are noticing some problems on the call screen: on certain devices (iOS 18.4RC) the normal call screen appears and the user can answer or decline the call, on other devices (iOS 18.3, especially with dynamic island) only a phone icon appears in the upper right corner and no possibility to answer or deny call. Any idea on why we are encountering that behavior? Thanks
Replies
0
Boosts
0
Views
193
Activity
Mar ’25
Call Tracking with CallKit Works in Debug Mode but Not in Release (TestFlight) – iOS
I am working on an iOS app using Flutter that tracks outgoing calls using CallKit. The call tracking functionality works perfectly in Debug mode but does not work when the app is published to TestFlight. I have already added Background Modes (voip, audio, processing, fetch) in Info.plist. I have added CallKit.framework in Xcode under Link Binary With Libraries (set to Optional). <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>aps-environment</key> <string>production</string> </dict> </plist> These are the necessary permission which I used in info.plist: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>BGTaskSchedulerPermittedIdentifiers</key> <array> <string>com.agent.mygenie</string> </array> <key>CADisableMinimumFrameDurationOnPhone</key> <true/> <key>CFBundleDevelopmentRegion</key> <string>$(DEVELOPMENT_LANGUAGE)</string> <key>CFBundleDisplayName</key> <string>MyGenie</string> <key>CFBundleDocumentTypes</key> <array/> <key>CFBundleExecutable</key> <string>$(EXECUTABLE_NAME)</string> <key>CFBundleIdentifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>mygenie</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>$(FLUTTER_BUILD_NAME)</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>$(FLUTTER_BUILD_NUMBER)</string> <key>LSRequiresIPhoneOS</key> <true/> <key>NSCallKitUsageDescription</key> <string>This app needs access to CallKit for call handling</string> <key>NSContactsUsageDescription</key> <string>This app needs access to your contacts for calls</string> <key>NSMicrophoneUsageDescription</key> <string>This app needs access to microphone for calls</string> <key>NSPhotoLibraryUsageDescription</key> <string>This app needs access to photo library for profile picture updation</string> <key>UIApplicationSupportsIndirectInputEvents</key> <true/> <key>UIBackgroundModes</key> <array> <string>voip</string> <string>processing</string> <string>fetch</string> <string>audio</string> </array> <key>UILaunchStoryboardName</key> <string>LaunchScreen</string> <key>UIMainStoryboardFile</key> <string>Main</string> <key>UISupportedInterfaceOrientations</key> <array> <string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array> <key>UISupportedInterfaceOrientations~ipad</key> <array> <string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortraitUpsideDown</string> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array> [code.txt](https://developer.apple.com/forums/content/attachment/0a327dbd-652e-41d5-8811-c462d09e0567) </dict> </plist> And below is the file are AppDelegate.swift, call_tracking_mixin.dart, & main_call.dart file for full knowledge
Replies
0
Boosts
0
Views
145
Activity
Mar ’25
Push Notification don't wake up my app
Hi everyone, We're experiencing an issue with our Flutter app that uses PushKit, CallKit, and Janus for handling VoIP calls. Everything works fine when the app is in the foreground, but when the app is in the background or completely closed (terminated state), the behavior is inconsistent: Sometimes, incoming calls are received as expected. Other times, the app does nothing, and the call is not delivered at all. Upon checking the console logs, we noticed that our app is being canceled (terminated by the system), which seems to be the reason why calls are not coming through. This happens randomly, making it difficult to reproduce consistently. Additional Details: The app is configured to handle VoIP notifications correctly. We are using PushKit to wake up the app and trigger CallKit for the incoming call UI. When the app is active, calls are handled correctly via Janus WebRTC signaling. We have verified that background modes for VoIP are enabled in the Info.plist. We suspect that iOS may be aggressively killing the app in the background, preventing incoming call notifications from reaching it. Questions: Has anyone experienced similar behavior with PushKit + CallKit on recent iOS versions? Could iOS be terminating the app due to background execution policies? Are there recommended best practices to ensure reliable delivery of VoIP notifications when the app is closed? Any insights or suggestions would be greatly appreciated! Thanks! Addional Information: this is the cancellation information at console: Received incoming message on topic hiperme.app at priority 10 por omisión 17:10:18.462084-0300 dasd CANCELED: com.apple.pushLaunch.hiperme.app:E8BACD at priority 10
Replies
0
Boosts
0
Views
177
Activity
Mar ’25
NSUserActivity in application(_:continue:restorationHandler:) not recognized as INStartCallIntent
Hello, experts! I'm working on a VOIP application that handles audio calls and integrates with CallKit. The problem occurs when attempting to redial a previously made audio call from the system's call history. When I try to handle the NSUserActivity in the application(_:continue:restorationHandler:) method, it intercepts the INStartAudioCallIntent instead of the expected INStartCallIntent. Background Deprecation Warnings: I'm encountering deprecation warnings when using INStartAudioCallIntent and INStartVideoCallIntent: 'INStartAudioCallIntent' was deprecated in iOS 13.0: INStartAudioCallIntent is deprecated. Please adopt INStartCallIntent instead. 'INStartVideoCallIntent' was deprecated in iOS 13.0: INStartVideoCallIntent is deprecated. Please adopt INStartCallIntent instead. As a result, I need to migrate to INStartCallIntent instead, but the issue is that when trying to redial a call from the system’s call history, INStartAudioCallIntent is still being triggered. Working with Deprecated Intents: If I use INStartAudioCallIntent or INStartVideoCallIntent, everything works as expected, but I want to adopt INStartCallIntent to align with the current iOS recommendations. Configuration: CXProvider Configuration: The CXProvider is configured as follows: let configuration = CXProviderConfiguration() configuration.supportsVideo = true configuration.maximumCallsPerCallGroup = 1 configuration.maximumCallGroups = 1 configuration.supportedHandleTypes = [.generic] configuration.iconTemplateImageData = UIImage(asset: .callKitLogo)?.pngData() let provider = CXProvider(configuration: configuration) Outgoing Call Handle: When making an outgoing call, the CXHandle is created like this: let handle = CXHandle(type: .generic, value: callId) Info.plist Configuration: In the info.plist, the following key is defined: &lt;key&gt;NSUserActivityTypes&lt;/key&gt; &lt;array&gt; &lt;string&gt;INStartCallIntent&lt;/string&gt; &lt;/array&gt; Problem: When trying to redial the audio call from the system's call history, the NSUserActivity received in the application(_:continue:restorationHandler:) method is an instance of INStartAudioCallIntent instead of INStartCallIntent. This happens even though INStartCallIntent is listed in NSUserActivityTypes in the info.plist and I want to migrate to the newer intent as recommended in iOS 13+. Device: iPhone 13 mini iOS version 17.6.1
Replies
0
Boosts
1
Views
271
Activity
Mar ’25
Is CallKit still not available in certain countries?
Is CallKit still not available in certain countries? like China? If it is, is there a way to get a list of countries?
Replies
0
Boosts
0
Views
96
Activity
Mar ’25
Push Notification
Hello. We're developing an app with Flutter that receives VoIP calls. However, when the app is in the background or closed, the push notification arrives, but the call doesn't. It works perfectly when the app is open. We use Firebase, Flutter, and JANUS WebRTC. We need to know what type of permissions or actions we should consider so that the app opens when it receives a call. How can we resolve this issue? Thank you very much.
Replies
0
Boosts
0
Views
145
Activity
Mar ’25
About 0xBAADCA11 error
I am developing "local push" VoIP application. I have a question about issues I found while testing this app. After repeating a test for 24 hours in which a incoming call followed by an immediate disconnect 0.1 seconds later, the iPhone of incommig call side encountered a 0xBAADCA11 error, causing iOS to force-close the app. (The incidence is low, occurring three times in 17280 times incoming call(24 hours.)) This problem found on iOS17.6.1 (iPhone11Pro). When the same test was performed on iOS18.2 (iPhoneSE3), the problem did not occur. Did iOS take something measures against the 0xBAADCA11 error between iOS17.6.1 and iOS18.2? If yes, I want to encourage customers to upgrade to the latest iOS version, please tell me about it? ※I have attached an ips files and sysdiagnose file of the 0xBAADCA11 error occurring. (please refer sysdiagnose also if you need.) FjSoftPhone-2025-01-16-113049.ips FjSoftPhone-2025-01-16-175253.ips FjSoftPhone-2025-01-17-070449.ips [sysdiagnose_2025.01.17_14-24-48+0900_iPhone-OS_iPhone_21G93.tar.gz] https://drive.google.com/file/d/1CV8laKzdnQxvwaAIOwMcXL8rAYL2jq35/view?usp=sharing
Replies
4
Boosts
0
Views
1.1k
Activity
Mar ’25
VOIP is not receiving calls
Hello, I am developing a calling service using CallKit and VOIP push. I have occasionally encountered a strange issue. The issue is that VOIP permanently fails to receive calls. I was previously informed that even if the device is blocked, it can receive calls again after 24 hours. Also, when I checked the device logic, it complied with the policy requirements set by Apple, including correctly calling CallKit's reportNewIncomingCall method. Once the issue occurs, no matter how many times I try, VOIP does not receive calls, and neither a device reboot nor checking the Device Console Log shows any logs related to CallKit or VOIP. I suspect this might be an issue with the VOIP token, and I believe that the only way to get a new one is to reinstall the app. Is that correct? Of course, after reinstalling, it works fine again, but this is very inconvenient. I don't think this is the right solution. Is there anyone who can share their insights on this issue? Thank you.
Replies
0
Boosts
0
Views
265
Activity
Mar ’25
Getting VoIP notifications to work and use iOS call UI when phone is locked/app is in background/Not running
Hey there my application allows users to have video calls with each other using Agora. I have successfully set up incoming call functionality on Android but on iOS I am struggling to get the call ui to appear when the app is not running/in background/locked. To my knowledge this is because there is much stricter security on iOS which is limiting me from calling this. When i initially set it up it worked at first when the app was in the background but I think I was failing to report the call to call kit in time and now it's not working. I'm not sure if I need access to this entitlement: com.apple.developer.pushkit.unrestricted-voip Which i believe is only for the big boys or if I make sure I'm reporting the call to call kit fast enough that I won't encounter this issue and it will consistently work in the background.
Replies
0
Boosts
0
Views
251
Activity
Mar ’25
Using `com.apple.developer.usernotifications.filtering` for developement
Ref: https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.usernotifications.filtering?language=objc Currently, it seems impossible to enable this entitlement for local development and testing without first going through Apple’s approval process. I would like to be able to test how it works on a side project without having to submit the form which seems designed for real app. There is any trick I can use?
Replies
1
Boosts
0
Views
277
Activity
Mar ’25
how can i get the LiveCommunicationKit events
i have codes looks like: import UIKit import LiveCommunicationKit @available(iOS 17.4, *) class LiveCallKit: NSObject, ConversationManagerDelegate { @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, conversationChanged conversation: Conversation) { } @available(iOS 17.4, *) func conversationManagerDidBegin(_ manager: ConversationManager) { } @available(iOS 17.4, *) func conversationManagerDidReset(_ manager: ConversationManager) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, perform action: ConversationAction) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, timedOutPerforming action: ConversationAction) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, didActivate audioSession: AVAudioSession) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, didDeactivate audioSession: AVAudioSession) { } @objc public enum InterfaceKind : Int, Sendable, Codable, Hashable { /// 拒绝/挂断 case reject /// 接听. case answer } var sessoin: ConversationManager var callId: UUID var completionHandler: ((_ actionType: InterfaceKind,_ payload: [AnyHashable : Any]) -&gt; Void)? var payload: [AnyHashable : Any]? @objc init(icon: UIImage!) { let data:Data = icon.pngData()!; let cfg: ConversationManager.Configuration = ConversationManager.Configuration(ringtoneName: "ring.mp3", iconTemplateImageData: data, maximumConversationGroups: 1, maximumConversationsPerConversationGroup: 1, includesConversationInRecents: false, supportsVideo: false, supportedHandleTypes: Set([Handle.Kind.generic])) self.sessoin = ConversationManager(configuration: cfg) self.callId = UUID() super.init() self.sessoin.delegate = self } @objc func toIncoming(_ payload: [AnyHashable : Any], displayName: String,actBlock: @escaping(_ actionType: InterfaceKind,_ payload: [AnyHashable : Any])-&gt;Void) async { self.completionHandler = actBlock do { self.payload = payload self.callId = UUID() var update = Conversation.Update(members: [Handle(type: .generic, value: displayName, displayName: displayName)]) let actNumber = Handle(type: .generic, value: displayName, displayName: displayName) update.activeRemoteMembers = Set([actNumber]) update.localMember = Handle(type: .generic, value: displayName, displayName: displayName); update.capabilities = [ .playingTones ]; try await self.sessoin.reportNewIncomingConversation(uuid: self.callId, update: update) try await Task.sleep(nanoseconds: 2000000000); } catch { } } } i want to listen the button event,but i can't find the solutions!please give me a code demo
Replies
0
Boosts
0
Views
233
Activity
Mar ’25
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?
Replies
1
Boosts
0
Views
337
Activity
Mar ’25
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:
Replies
0
Boosts
0
Views
387
Activity
Mar ’25
Live Caller ID on iOS does not work - client requests not reaching backend
I'm reaching out to see if anyone else is experiencing issues with the Live Caller ID feature on iOS. We recently encountered a problem where the feature stopped working entirely. Here's a brief overview of the situation: We were monitoring test traffic on our backend and noticed everything came to a halt around 1:00 AM UTC on November 15th. After this time, any attempts to reach our backend through calls failed completely. I tested this across multiple devices running iOS 18.2 and iOS 18.0. I used both TestFlight builds and development builds via Xcode, which should communicate directly with our backend. I experienced the problem on our main application as well as a dedicated test app. To troubleshoot further, I even set up a local server on localhost and tried directing requests there, but the requests did not reach the local server when a call was received. Further debugging in Console.app revealed the following error: identity request returned error: Error Domain=com.apple.CipherML Code=400 "Error Domain=com.apple.CipherML Code=401 "Unable to request data by keywords batch: failed to fetch token issuer directory" However, when I manually tried to hit our server endpoint using curl, the request successfully reached the server: curl https://our_server/something hb_method=GET hb_uri=/something [Hummingbird] Request -- log on backend This suggests that while our backend is responsive, the requests from the iOS client side are simply not being initiated.
Replies
9
Boosts
3
Views
1.6k
Activity
Mar ’25
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.
Replies
3
Boosts
0
Views
675
Activity
Mar ’25
CallKit outgoing calls UI
i thought it is impossible to have CallKit show system UI for outgoing calls. but then i saw this: "For incoming and outgoing calls, CallKit displays the same interfaces as the Phone app..." https://developer.apple.com/documentation/callkit how do i present it though? or is this a documentation error?
Replies
2
Boosts
1
Views
1.3k
Activity
Mar ’25
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!
Replies
4
Boosts
1
Views
535
Activity
Mar ’25
Is it possible for a Live Caller ID server to specify different datasets?
In the documentation for the example Live Caller ID server (https://swiftpackageindex.com/apple/live-caller-id-lookup-example/main/documentation/pirservice/testinginstructions) there is an example service-config.json. file shown (without thorough documentation). That config file, and the whole of the instructions, center around there being two datasets of numbers: block and identity. My question is - is it possible for more than one dataset to be specified i.e. for block1 and block2 to be specified? The use case for this would be - suppose the Live Caller ID server has a set of numbers it has identified as being nuisance callers and so it lists these in the block section. However user A might want all these nuisance callers to be blocked but user B does not. Therefore the Live Caller ID extension on the handset would need to use a different dataset on the server so that user A's calls from a set of numbers is blocked, but user B's are not. Note that I'm not suggesting that the Caller ID server should be capable of storing individual user's preferences. All that would be required would be two data sets: one where blocked content is none and and one where blocked content is some. Then a user/app could switch between them as indicated by the user. Is that possible? If the database structure and service-config.json etc. is not configured to permit that, then could two different servers be set up to achieve this instead? i.e. so the server url specified in the app's extension can be set at run time and not at compile time?
Replies
5
Boosts
0
Views
1k
Activity
Mar ’25
Can a Live Caller ID server supply live data or must it be static?
With the Live Caller ID example server, the caller lookup dataset is defined in an input.txtpd and processed by running a ConstructDatabase command which creates a block.binpb and an identity.binpb file. In other words, a static input file is being processed into static block and identity files. However, in the real world, the data content for identified and blocked numbers is something which is in a constant state of flux and evolution, as new numbers becoming available, old ones become stale, numbers which were initially considered safe change into being considered malicious etc. etc. Is the example server just that, merely an example using fixed datasets, and an actual production server is able to use live every changing data to formulate its response back to the iPhone OS query? Here's a concrete use case - suppose it's a requirement to permit US nanp numbers but to block anything else. The total number of non US nanp numbers is so large and ever changing that it would be unfeasible to attempt to capture them in an input.txtpd file and then process that, and then to re-capture and re-process it endlessly. Instead what would be required is the ability for the Live Caller ID server to evaluate at query time, using a regular expressions for example, if a number is nanp or not. Is this possible?
Replies
5
Boosts
1
Views
933
Activity
Mar ’25