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

99 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

I would like to know why I didn't receive a VoIP notification.
We have modified the program as we received in the previous(thread 764479) issue. Our program works very well and the notification problem has been almost solved in the test. Then, we tested it in the user's environment. At that time, one of the three iPhones stopped receiving notifications. After 10 minutes, VoIP notifications were received again. This device received PUSH notifications even when VoIP notifications did not come. We must explain to the user why this incident occurred. We would like to know if these three notifications were sent correctly to the device. Also, is there any other way for us to deal with this other than improving the network? [APNS LIST]Nov. 20th could not receive(failed) 15:06:13 5793987C-D1A4-811F-917F-87DD7F5083B3 15:07:09 667E0A2F-43B5-37FC-2F2A-45A6C27EFC34 15:19:31 1353DF78-519E-B1DC-82B7-8B890E59FE37 received(success) 15:04:09 19CC1937-533A-9AF4-9472-41C839E461D7 15:35:00 CD23AC57-6EC7-4523-941F-B103EDB4DEFB
0
0
23
18h
Handle InSendMessageIntent in the app
Hi, I'm implementing InSendMessageIntent handling in our app. I can handle InSendMessageIntent through extension, but handling also includes business logic like authorisation status and some heavy operation which I can't expose from the main target. I tried to handle it in-app, but func application(_ application: UIApplication, handlerFor intent: INIntent) -> Any? didn't trigger. At the first glance the configuration looks correct - the InSendMessageIntent is added under INIntentsSupported and UIApplicationSupportsMultipleScenes is set to YES in info.plist. After that reply with message button disappeared from the incoming Voip callKit screen. So I had a question - Is this intent possible to be handled in-app?
0
0
40
1d
Call Blocking and Identification Issue in iOS 18
When Call Blocking and Identification is enabled, information such as Caller Name, number and Call Identification Label is displayed correctly in the incoming call screen. But in Recents screen the call record is not displaying any name or number but instead displays only the Call Identification label that was passed in CXCallDirectoryProvider is displayed. Note: This issue is not observed when the call blocking and identification permission is not granted and the same code is working fine in iOS 17.x
0
0
67
3d
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.
4
2
211
1d
It didn't get any notifications after changing the device token. (Voip, APNs)
I am developing the iOS application using PushKit and APNS. Some users didn't get any notifications after some events, such as updated iOS 18 or a new version from the App Store. After the event had changed device tokens (PushKit, APNS). When the app has launched, register the iOS system with PushKit and APN tokens and upload it to our server. Most of the time, the tokens didn't change. I was investigating the console log when making a call from another device or sending APN. But I didn't get any logs from it. Normally it is looking following apsd, callserviced, Springboard, delivering or launching the app when getting a voip push. The issue was solved after reinstalling the app. But it still occurred with users—about 1% of total.  How do I solve the issue without reinstalling the app?
2
0
293
1w
Is there a way for a device to detect when VoIP Push has been blocked?
Hello, I am developing an application using VoIP Push and CallKit. I have a question: Starting with iOS 13, I understand that under the VoIP Push policy, if reportNewIncomingCall is not called continuously, the VoIP Push may be blocked. Is there a way to determine if the device has been blocked? I am curious whether PKPushRegistry itself is unable to receive pushes or if reportNewIncomingCall returns an error when it is blocked. If push notifications are not being received, what should I do to resume receiving them? Thank you.
3
0
149
2d
CallKit breaks web based MediaStreams
We're integrating a web based group calling application within a native iOS application and finding that every time a CallKit session gets fully established the web based media streams break, rendering as gray with no audio. Up to iOS 18 we worked around it by not fulfilling the call start action but that's no longer an option as the audio stopped getting automatically redirected to the speakers. We would now need the CXProvider's didActivateAudioSession callback but that would break the video. The sample project loads up a simple webpage in a WKWebView which contains a video tag streaming the media from the device's camera. At the same time it sets up a new CallKit session by requesting and fulfilling a CXStartCallAction transaction. You will notice that the media doesn't render and, if you are to follow the warnings we left, you will find that not fulfilling the CXStartCallAction fixes it. Unfortunately that's not a workaround we can use as we need the CXProvider delegate to inform us about audio session changes so we can redirect the audio to the speaker (so the proximity sensor doesn't activate and locking the screen doesn't end the call) Any insights or workarounds would be greatly appreciated.
4
1
217
2w
After updating iOS 18 CXCall is giving wrong values in hasConnected and hasEnded when user reject the call
Dear Apple team, I would like to report a problem that started after update my iPhone to iOS 18.0.1. When user receives a call and reject, CXCall is giving wrong values compared the previous version of iOS (minor of 18). In iOS 17.7, we received this values: hasConnected = false hasEnded = true iOS 18.0.1 we received 2 CXCall events: first event hasConnected = true hasEnded = false second event hasConnected = true hasEnded = true This behaviour is strange and not intuitive, and if we check the documentation, don`t make sense: A call is considered connected when both caller and callee can start communicating and A call is considered ended when the user disconnects or all other callers disconnect. Our code is very simple and use callObserver function to make the flow: public func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) { if call.hasConnected, !call.hasEnded { //GoToViewControllerX } if call.hasEnded { //DoSomething } } With the behavior of iOS 18 the project will enter in first conditional and then will enter in second conditional. I need some help or some instruction because the intention ir only enter in first conditional if the call really happens.
2
3
235
Oct ’24
Inconsistent Live Caller ID Lookup Performance
I've noticed delays with the Live Caller ID Lookup feature, taking around 3 to 6 seconds to complete, even on repeated lookups. This seems odd since there's no server activity during these repeats, suggesting the information might be coming from a cache. Most of the time, it’s fast, but there are cases when it's unexpectedly slow, and I haven’t quite figured out the pattern yet. Is anyone else seeing this issue? FB number FB15372765 - with sysdiagnose and video demonstrating the delay.
0
0
178
Oct ’24
App Intents is not able to start an outgoing call with CallKit when the app is backgrounded
I am currently working on integrating an app with Siri, adding support for starting VOIP calls and sending messages. Although it is understood it is recommended to use SiriKit for calling and messaging, I would like to allow users to select a profile to use for calling. As far as I am aware the notion of selecting a profile to call from is not something SiriKit supports, therefore, it was decided to go with App Intents to allow for more control over the parameters utilized to start calls. After integrating VOIP calling with App Intents, I noticed CallKit is not able to start calls when the App Intent is invoked from the background. I get the following error: Error Domain=com.apple.CallKit.error.requesttransaction Code=6 "(null)” This seems to correspond to the CXErrorCodeRequestTransactionError invalidAction. This error only happens when the intent is invoked from the background. Changing the App Intent property openAppWhenRun to true solves the issue as it brings the app to foreground before running the intent. However, I would like to support starting calls from the background to avoid making users unlock their phones prior to starting a call with Siri to make it a truly hands-free experience. I suspect the desired behavior is possible, most likely with SiriKit, as some famous VOIP calling apps (i.e. WhatsApp, Messenger, etc) exhibit the behavior I described. However, is there any way to start calls from the background with App Intents? Or is the desired behavior something exclusive to SiriKit? I have pasted three code snippets below that can replicate the issue. At the moment I am on Xcode Version 15.3, macOS Sonoma 14.6.1, and testing on iOS 16.6.1 To demonstrate the issue I have created the following CXProviderDelegate: class CallManager: NSObject, CXProviderDelegate { func startCall() { let callKitProvider = CXProvider(configuration: CXProviderConfiguration()) callKitProvider.setDelegate(self, queue: nil) let callKitController = CXCallController() let recipient = CXHandle(type: .generic, value: "Demo Outgoing Call") let uuid = UUID() let startCallAction = CXStartCallAction(call: uuid, handle: recipient) let transaction = CXTransaction(action: startCallAction) callKitController.request(transaction) { error in if let error { print(error) } else { print("no errors") } } callKitProvider.reportOutgoingCall(with: uuid, connectedAt: nil) } func providerDidReset(_ provider: CXProvider) { // no-op, not required to demonstrate the issue } } Then, I have a UIViewController that is the only screen of this example app: class ViewController: UIViewController { @IBOutlet weak var startCallButton: UIButton! override func viewDidLoad() { super.viewDidLoad() startCallButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) } @objc func buttonTapped() { let manager = CallManager() manager.startCall() } } As for app intents, I put together a very simple intent to trigger the start of an outgoing call: struct StartCall: AppIntent { static var title: LocalizedStringResource = "Start Call" static var openAppWhenRun = false func perform() async throws -> some IntentResult { let manager = CallManager() manager.startCall() return .result() } } When the UIViewController is presented and I tap the button to start a call I see the green call banner appear and "no errors" is printed to the console as intended. However, when I open the Shortcuts app and run the app intent, the green banner does not appear and the message Error Domain=com.apple.CallKit.error.requesttransaction Code=6 "(null)” is printed to the console.
1
0
194
Oct ’24
After iOS18.0 rejects the call, CXCall's hasConnected is YES, which should be NO.
Dear Apple R&D Team, I want to report a bug of CallKit caused by Voicemail in iOS18.0. The following are the header files referenced by our code: #import <CallKit/CXCallObserver.h> #import <CallKit/CXCall.h> Our VoIP app uses the callObserver callback function provided by CXCallObserverDelegate to monitor changes in the system phone status (see the attached picture). The problems we encountered are: Before upgrading to iOS18.0, when we rejected a call, we would receive a callObserver callback, and the status value of hasConnected of CXCall was NO; After upgrading to iOS18.0, when we also rejected a call, the status value of hasConnected of CXCall was YES. So we checked the new features of iOS18.0 and found that it was the influence of the new feature Voicemail. On iOS18.0 devices, if you reject a call, you will enter the Voicemail state by default, which means that I rejected the call, but callObserver told me that the call was connected, which is inconsistent with the user's intuitive experience and will also cause our App to respond incorrectly (cannot resume audio automatically). In fact, the Voicemail function is enabled by default for devices upgraded to iOS 18.0. After I reject a call, I have to wait for the caller to hang up before I can receive callObserver telling me that the call has been hung up. This experience is very bad, because when the caller does not hang up the call, our App cannot sense that I have hung up the call and thinks that I am still on the call, but in fact I did hang up the call. Please refer to the code in the attached picture. According to our understanding, the status should flow like this: When I receive an incoming call, the callObserver callback will trigger, call.hasConnected is NO and call.hasEnded is NO; When I reject the call and switch to Voicemail, the callObserver callback will trigger, call.hasConnected should be NO and call.hasEnded should be YES; When I manually restore the call through Voicemail, the callObserver callback will trigger, call.hasConnected should be YES and call.hasEnded should be NO; When the caller or I finally hang up the call, the callObserver callback will trigger, call.hasConnected is YES, call.hasEnded is YES; However, the current status is as follows: When I receive an incoming call, the callObserver callback will trigger, call.hasConnected is NO and call.hasEnded is NO; When I reject the call and switch to Voicemail, the callObserver callback will trigger, call.hasConnected is YES and call.hasEnded is NO; When I manually restore the call through Voicemail, the callObserver callback will not trigger; Only when the caller finally hangs up, the callObserver callback will trigger, call.hasConnected is YES and call.hasEnded is YES; Our request is very simple. We need to pause audio when a call comes in and resume audio when the call is hung up or rejected. This is our sample code: - (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call API_AVAILABLE(ios(10.0)) { bool pause_audio = false; BOOL calling = !call.onHold && !call.hasConnected && !call.hasEnded; BOOL disconnected = !call.onHold && !call.hasConnected && call.hasEnded; BOOL connected = !call.onHold && call.hasConnected && !call.hasEnded; BOOL hang_up = !call.onHold && call.hasConnected && call.hasEnded; if (calling) { xc_log(XC_LOG_INFO, "A phone call is %s", call.outgoing ? "outgoing" : "incoming"); pause_audio = true; } else if (disconnected) { xc_log(XC_LOG_INFO, "An %s phone call has been disconnected", call.outgoing ? "outgoing" : "incoming"); // action of phone call end, resume audio } else if (connected) { xc_log(XC_LOG_INFO, "An %s phone call has just been connected", call.outgoing ? "outgoing" : "incoming"); pause_audio = true; } else if (hang_up) { xc_log(XC_LOG_INFO, "An %s phone call has been hang up", call.outgoing ? "outgoing" : "incoming"); // action of phone call end, resume audio } else { xc_log(XC_LOG_INFO, "Unknown telephony state occured"); } if (pause_audio) { dispatch_async(dispatch_get_main_queue(), ^{ // action of phone call begin, pause audio }); } } I would appreciate any help !!!
0
2
225
Oct ’24
callkit and contact app
Hello, I am a developer currently working on a personal contact management app. What is the app? My app stores additional information beyond basic contact details. Therefore, instead of using the Contacts framework, I manage contact objects using Core Data. What am I trying to achieve? I want to display additional information on the caller ID screen when a call is received from a number stored in my app. What have I tried? I’ve attempted the following methods without success: 1. Call Directory Extension: I thought using this method would allow me to display additional information from Core Data on the call screen. However, I learned that when a call is received, the iOS system first searches for the phone number in the Contacts app and only looks to the Extension app if no match is found. Therefore, displaying contact information from my app seems unfeasible. 2. Custom Call UI: Using CallKit seemed like a viable option to display the necessary information during a call, but it appears to only be possible with VoIP apps. My app does not support VoIP calls, so this method was also not implementable. I am wondering if there are any technologies available that could help me achieve my goal, or if there’s something I might be missing. Any advice would be greatly appreciated. Thank you! If a similar question has been asked, I apologize for the repetition.
3
0
300
Oct ’24
CallKit: CXCallEndedReason.remoteEnded when the call is ended with reason=answerTimeout
Hello, experts! During a VOIP call, the following happens: device 1 makes a call to device 2 device 2 deliberately does not receive the call some time passes, timeout is triggered and the call is terminated with CXCallEndedReason = remoteEnded, as evidenced by a line in the logs of the incoming call: `[info] reportCallWasEnded callId=[***-***-***], reason=[CXCallEndedReason(rawValue: 2)].` What is the reason why CXEndCallAction may be called from CXProviderDelegate even though the call was not manually terminated by clicking on the “End Call” button
2
0
238
Oct ’24