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?
CallKit
RSS for tagDisplay 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
98 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
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
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.
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?
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.
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.
Is it legal to use incoming call UI for displaying a scheduled fake call? Does it conform to App Review policies?
The approach also means there's no VoIP service integration for the app one's going to distribute
Is there a way for my app to know that a phone number has just been messaged to or a call to 911 just started? Or SOS has just been executed by the user?
Hi community,
I'm an iOS developer developing a proof of concept for Automaker apps, and I'm trying to make a phone call with the following code:
let url = URL(string: "tel://1234567890")
But the banner is not shown in the Carplay Automaker App, if I have the same view opened in the iOS application the banner is shown and I can make the phone call...
Thanks,
David Cosialls.
Need help from Apple to provide more details on what can contribute to "CXErrorCodeRequestTransactionErrorInvalidAction".
For the same client build, we are seeing a spike of errors only from older OS (< 16.5) with error code 6 (.invalidAction) when requesting a transaction with CXStartCallAction. This happened after we update to XCode 16.1.
Hello
Iphone - ISO 17.6
I'm looking for an example on how I can access and manage a list of blocked phone contacts from CallKit ? / Swift.
Ive seen a number of posts which suggest this may not be possibe
Any hints / guidance would be appreciated
Thank you
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.
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.
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.
Hi,
Incoming calls were working fine when the app was run from Xcode in both production and debug modes. I added the APS Environment to production, but after releasing it on TestFlight, it's not working, and I am not receiving PushKit notifications.
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 !!!
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.
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
Since I updated to iOS 18, CallKit-linked caller not display on screen of CarPlay.
CarPlay display only "{App Name} Caller ID".
When iOS version was 17.x, CarPlay displayed caller name of CallKit-linked contact.
I think CarPlay should perform the same function as iOS 17.
Please review it.
Dual SIM management on the iPhone is not very efficient. I am using an iPhone 13, and I have to frequently change the SIM line because sometimes I recharge one SIM, and other times I recharge the second SIM. I have selected the default SIM line in the settings, which means calls should always go through the default set SIM line. However, this is not happening. I have to manually go to the contact of the person and change the SIM line before making a call. Could you provide a feature where, when calling any person, the call always goes through the selected default SIM line?