Hello Apple Developer Community,
I'm developing a call-blocking app for iOS and have encountered an issue with iOS 18. Despite calls being successfully blocked by our app's Call Directory extension, they are still appearing as unanswered calls in the native Phone app.
Details:
iOS version: 18
App uses CallKit and Call Directory extension
Calls are blocked successfully (not ringing on device)
Blocked calls show up as "Unanswered" in Phone app's recent calls list
Expected behavior: Blocked calls should not appear in the Phone app's recent calls list.
Actual behavior: Blocked calls appear as "Unanswered" in the recent calls list.
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
157 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have been playing around with getting the Live Caller ID example project setup yet I cannot get passed the initial configuration. I have the app extension running on my device and the server running on the correct host and port so things are working in that sense, yet when I go to the Call Blocking & Identification Services to toggle on my extension I see that the /config endpoint is failing with the following error:
Invalid existingConfigIds count 1. Expected 0 or 0.
The existingConfigIds has one entry with a Data object of zero bytes.
I’m not sure where/why this is getting added upon initialization. Has anyone seen this occur? I followed the testing instructions as far as I can tell and haven’t seen this issue discussed elsewhere.
I am working on Agora Voice Call and using CallKit to manage incoming and outgoing calls.
Issue:
When I accept a call, CallKit goes behind my app. I want CallKit to remain in front of my app. Please guide me.
I've been testing the Live CallerID feature using the Apple-provided local server example - live-caller-id-lookup-example. I've been running a local server with tunneling using ngrok for the initial setup. Everything was working perfectly with the following setup:
@main
final class CallerID: LiveCallerIDLookupProtocol {
var context: LiveCallerIDLookupExtensionContext {
LiveCallerIDLookupExtensionContext(
serviceURL: URL(string: "https://example-tunnel.ngrok.io")!,
tokenIssuerURL: URL(string: "https://example-tunnel.ngrok.io")!,
userTierToken: Data(base64Encoded: "BBBB")!
)
}
}
However, after I updated the URLs to the production ones, I encountered an issue:
@main
struct CallerID: LiveCallerIDLookupProtocol {
var context: LiveCallerIDLookupExtensionContext {
LiveCallerIDLookupExtensionContext(
serviceURL: URL(string: "https://example.net/")!,
tokenIssuerURL: URL(string: "https://example/issue")!,
userTierToken: Data(base64Encoded: "BBBB")!
)
}
}
The problem is that during calls or when updating PIR parameters, the application still attempts to connect to the initial ngrok tunnel URLs instead of using the new production URLs. I can confirm this because the logs on my local server show incoming requests, indicating that the application is still referencing the old ngrok tunnel URLs.
Steps I’ve taken to resolve the issue include:
Deleting and reinstalling the application.
Using reset(forExtensionWithIdentifier:)
Unfortunately, these attempts have not been successful. I even extracted the binary of the app and extension to inspect the strings, confirming that the correct production URLs are present.
The server was started with the following command:
PIRService --hostname 127.0.0.1 service-config.json
Could this be some sort of caching bug on the iOS side, or am I missing something?
Following up on a previous thread that was marked as resolved, we're observing that the behavior of blocked calls in iOS 18.2 hasn't changed as indicated.
Current behavior in iOS 18.2:
Calls blocked by Call Directory extensions still appear as "unanswered" in the Phone app's call history
The calls are successfully blocked (don't ring) though
There's no indication in the call history that these calls were blocked
Expected behavior (as previously indicated would be fixed in iOS 18.2 beta 3):
Blocked calls should be labeled as "Blocked"
Should show which app blocked them
This continues to cause confusion among users who expect blocked calls to either be clearly labeled or not appear in their history at all. We're still receiving regular user complaints about this behavior.
Has there been any change in the timeline for addressing this? Any information would be helpful for both developers and users.
Thank you in advance.
What determines whether the live caller ID call extension sends a /queries request with an EvaluationKey instead of an EvaluationKeyMetadata.Identifier? Is this behavior configurable through our app?
In the live-callerid-lookup-example, the code checks if the PirRequest contains an EvaluationKey and uses it for evaluation if present; otherwise, it defaults to the uploaded key. However, during testing with the live caller ID extension, we observed that the client system (iPhone) consistently sends /queries requests using only EvaluationKeyMetadata.Identifier.
Is it possible for the client to send queries with an EvaluationKey to reduce storage requirements?
In the "Refresh the Data" section, it is mentioned that "The system periodically refreshes these parameters automatically." Could you provide more details on the specific timing or frequency of these automatic refreshes? For example, do factors such as Low Power Mode, power-saving mode, or a screen-locked state affect the frequency or occurrence of these updates?
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 am developing a VOIP app which should also work in China region. I want to detect whether there are any other calls active or ended. This functionality is can be achieved using Callkit CXCallObserver. But CallKit cannot be used in China. So is there any other alternative way to achieve what CXCallObserver offers?
Our company application uses callkit for livestream but is not available in china which make Apple not to approve the app. can any one help with what i can do. The live stream is one of the key feature of the app. Or is it possible to restrict download from china
How can I show my VoIP calling app in the same list as Facetime and Whatsapp as shown in the image?
My app implements VoIP calls and is integrated with CallKit.
Any tip would be appreciated!
I noticed the following behavior with CallKit when receiving a VolP push notification:
When the app is in the foreground and a CallKit incoming call banner appears, pressing the answer button directly causes the speaker indicator in the CallKit interface to turn on. However, the audio is not actually activated (the iPhone's orange microphone indicator does not light up).
In the same foreground scenario, if I expand the CallKit banner before answering the call, the speaker indicator does not turn on, but the orange microphone indicator does light up, and audio works as expected.
When the app is in the background or not running, the incoming call banner works as expected: I can answer the call directly without expanding the banner, and the speaker does not turn on automatically. The orange microphone indicator lights up as it should.
Why is there a difference in behavior between answering directly from the banner versus expanding it first when the app is in the foreground? Is there a way to ensure consistent audio activation behavior across these scenarios?
I tried reconfiguring the audio when answering a call, but an error occurred during setActive, preventing the configuration from succeeding.
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setActive(false)
try audioSession.setCategory(.playAndRecord, mode: .voiceChat, options: [.defaultToSpeaker])
try audioSession.setActive(true, options: [])
} catch {
print("Failed to activate audio session: \(error)")
}
action.fulfill()
}
Error Domain=NSOSStatusErrorDomain Code=561017449 "Session activation failed" UserInfo={NSLocalizedDescription=Session activation failed}
I noticed the following behavior with CallKit when receiving a VolP push notification:
When the app is in the foreground and a CallKit incoming call banner appears, pressing the answer button directly causes the speaker indicator in the CallKit interface to turn on. However, the audio is not actually activated (the iPhone's orange microphone indicator does not light up).
In the same foreground scenario, if I expand the CallKit banner before answering the call, the speaker indicator does not turn on, but the orange microphone indicator does light up, and audio works as expected.
When the app is in the background or not running, the incoming call banner works as expected: I can answer the call directly without expanding the banner, and the speaker does not turn on automatically. The orange microphone indicator lights up as it should.
Why is there a difference in behavior between answering directly from the banner versus expanding it first when the app is in the foreground? Is there a way to ensure consistent audio activation behavior across these scenarios?
I am currently working on implementing the Live Caller ID Extension for my iOS app, and I understand that a backend server is required for this functionality. While I’ve gone through Apple’s documentation, the details on the backend setup are limited and not very clear for my backend team to implement it effectively.
Could someone provide a more detailed explanation or sample implementation of the backend server required for this extension? Specifically, we are looking for:
A clear understanding of the APIs and endpoints the backend needs to expose.
Any authentication mechanisms required for communication with the extension.
Data format (e.g., JSON structure) for requests and responses.
Example code or additional resources, if available.
Any help or guidance in understanding the exact backend requirements would be greatly appreciated.
I've found an app that has a call blocking feature an is able to add more than 10_000_000 entries. As I understand it doesn't use more than one extension for it because I see only one in the Call Blocking & Identifying settings menu. How to implement that? My limit now is around 1_800_000 entries.
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
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?
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.