I am developing an app where the primary feature is to notify users.
To deliver notifications more effectively, I am considering using PushKit and CallKit.
Would it be acceptable under the guidelines to use PushKit and CallKit as an optional feature for an AI agent to notify users via a phone call?
Notifications
RSS for tagLearn about the technical aspects of notification delivery on device, including notification types, priorities, and notification center management.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
@App Store Commerce Engineer hi, have you already implement something for handle server notification if user buy non consumable purchases product, how my server should know if user boutght something ?
Topic:
App & System Services
SubTopic:
Notifications
We're trying to add simple notifications to our CarPlay integration that should open certain template when pressed, but the issue is that when pressing this notification on CarPlay screen nothing is invoked in the code (presumably didReceive should be invoked). All works fine with the same notification but pressed on the iPhone screen - didReceive is invoked properly. How should I handle the action when push notification is pressed on CarPlay screen?
Hello,
We have a Push-to-Talk (PTT) application that is already well established and widely used. Our app has the proper VoIP entitlement, which we are using to wake up the app and establish a WebSocket connection for real-time communication. We are also using CallKit as a supporting mechanism, but not as the primary interaction upon receiving the VoIP Push, since our use case differs from traditional full-duplex VoIP calls.
While our implementation works correctly in many cases, we have noticed a consistent issue where, after multiple VoIP Push notifications, the system still delivers the push, but prevents the WebSocket from reconnecting.
At this point, all connection attempts return errors such as:
• "Software caused connection abort"
This issue persists until the app is manually relaunched, after which the behavior resets and repeats.
We are aware that VoIP Push was originally designed for full-duplex calls, but since Apple allows its use for other purposes through the entitlement, we would like to understand why this limitation is occurring and how to handle it properly.
Questions:
1. Is iOS enforcing stricter background execution rules after multiple VoIP Push events within a short period?
2. Are there any recommended best practices to ensure reliable WebSocket reconnection in this scenario?
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.
I have converted a large part of the data, but only 5% of the data was successfully converted. The failed devicetoken shows "bad devicetoken" when accessing APNS. Here are examples of failed conversions devicetoken. Is there any official documentation for this part?
DeviceToken Orgin \xc2\xa1\xcb\x9cr\xc3\x81\xe2\x80\x9e\x01b\xc3\xbce1pf\t\xc2\xa7\xc3\x82v}\xc3\xa1\xc3\x9a:?\r\n\xc3\xa5\xc6\x92\xc3\xb7y\xc3\x9e\xe2\x80\x9c\xc3\x89r
Is there a public method to know when an APNS has appeared on the screen?
wrapping up a very high end photogrammetry app, using the front facing camera and screen illumination-
incoming notifications completely throw off the math.
Ideally, it would be great to turn on Do Not Disturb for the short process, but we’d settle for just the detection of the notification banner.
also: extra credit - programattically adjusting Auto Dimming, and True Tone would be lovely too.
We are observing unexpected behavior in Apple Push Notification Service (APNS) delivery and would appreciate clarification and guidance. Below is a detailed
breakdown of the scenario and related questions.
Abbreviations:
APNP – Apple Push Notification Provider
APNS – Apple Push Notification Service
Scenario:
User1 is registered on iOS device1.
Flight Mode is enabled on iOS device1.
User2 initiates a call to User1 (Time t = 0 sec).
User2 cancels the outgoing call after 5 seconds (Time t = 5 sec).
Flight Mode is disabled on iOS device1 after 20 seconds (Time t = 25 sec).
Observation:
iOS device1 displays an incoming call notification (CallKit UI) after flight mode is turned off, despite the call being cancelled by User2.
This notification disappears automatically after approximately 8–10 seconds.
Logic Flow:
At time t = 0, our APNP sends a VoIP push (priority) to APNS for the incoming call.
Since device1 is in flight mode, APNS cannot deliver the push.
At t = 25 sec, after flight mode is turned off, APNS delivers the cached VoIP push to device1.
The app takes ~5 seconds to initialize (CSDK setup, SIP registration, etc.).
It eventually receives a SIP NOTIFY with state="full" and empty dialog info (indicating no active call).
Consequently, the CallKit incoming call is removed after ~8 seconds.
Questions:
→ We set the apns-expiration header to 0, expecting that the VoIP push would not be delivered if the device was unreachable when the push was sent. However, APNS still delivers the push 20–30 seconds later, once the device is back online.
Q. Why is the apns-expiration header not respected in this case?
→ Upon receiving the VoIP push, we require ~10–12 seconds to determine if a visible CallKit notification is still relevant (e.g., by completing SIP registration and checking for active dialogs).
Q. Is it acceptable, per Apple guidelines, to intentionally delay showing the CallKit UI (incoming call) for 10–15 seconds after receiving the VoIP push?
→ Apple documentation states that the priority VoIP push channel should be used only for notifying incoming calls, while regular (non-VoIP) pushes should be used for other updates, including call cancellations.
Q. What is the rationale behind discouraging the use of the priority VoIP push channel for call cancellation events? In some cases, immediate cancellation notification is as critical as the initial incoming call. Would Apple consider it acceptable to occasionally use the priority VoIP channel for rare call-cancellation scenarios without risking throttling or suspension?
→ In our implementation, we send an incoming call notification via the priority VoIP channel. Shortly after, we send a call cancellation notification on the regular push channel, marked with "content-available": 1. We expect this regular push to wake the app (triggering application:didReceiveRemoteNotification:fetchCompletionHandler:), but in practice the app never wakes, and our debug logs inside that delegate method never appear.
Q. Under what exact conditions does a "content-available": 1 regular push fail to wake the app when it follows a VoIP push? Are there additional requirements (e.g., background modes, rate limits, power optimizations) that could prevent the delegate from being called?
→ According to Apple documentation: “APNs stores only one notification per bundle ID. When multiple notifications are sent to the same device for the same bundle ID, APNs keeps only the latest one.” However, in our tests: If a device is offline when APNs receives both: (a) a priority VoIP push for an incoming call, (b) a regular push for call cancellation (same bundle ID), Upon the device reconnecting, APNs still delivers the earlier VoIP push, instead of discarding it and delivering only the most recent (cancellation) notification.
Q. Why doesn’t APNs replace the queued VoIP push with the newer regular push when both share the same bundle ID? Is this expected behavior due to channel type differences (VoIP vs. regular), or is there a way to ensure that the latest notification (even if regular) supersedes the earlier VoIP push?
We’d appreciate your input or recommendations on handling such delayed pushes and any best practices for VoIP push expiration handling and call UI timing.
Discrepancy between App Store Server API `expiresDate` and iOS Settings subscription expiration date
I am developing an iOS app that uses App Store Server API (v2) for auto-renewable subscriptions.
I noticed a discrepancy between the expiration date returned by the API and the date displayed in iPhone Settings > Subscriptions:
App Store Server API expiresDate: 2025-09-12T12:10:25 (KST)
iOS Settings > Subscriptions: 2025-09-11 (one day earlier)
My understanding:
The API’s expiresDate is the precise UTC timestamp.
The Settings UI might display the "last full calendar day" for UX purposes.
Questions:
Is this behavior (UI showing one day earlier) an intentional Apple policy?
If so, is there any official documentation or guideline explaining this behavior?
Should developers always rely on the API’s expiresDate for subscription state management?
This discrepancy is confusing for both developers and end users, so any clarification or official reference would be greatly appreciated.
Topic:
App & System Services
SubTopic:
Notifications
I’m building a standalone Apple Watch smart alarm app that should trigger alarms on the watch in response to Bluetooth or internet events.
This means the app operates in the background and attempts to trigger an alarm when such an event occurs. As far as I know, the appropriate API for this is WKExtendedRuntimeSession.notifyUserWithHaptic:repeatHandler.
However, I can’t seem to start an extended runtime session while the app is in the background. I’m getting the following error:
-[WKExtendedRuntimeSession _invalidationReasonAndDelegateCallbackErrorForError:outCallbackError:]:729:
WKExtendedRuntimeSession hit internal error.
Error Domain=com.apple.CarouselServices.SessionErrorDomain
Code=17 "startSession cannot be called on a scheduled session"
UserInfo={NSLocalizedDescription=startSession cannot be called on a scheduled session}
Calling notifyUserWithHaptic directly also similarly fails.
It seems notifyUserWithHaptic is intended to be scheduled during a foreground session to trigger at a later time, rather than being called ad hoc from a background context.
Is there any way to create a proper alarm view on the Apple Watch from a background execution context?
sending the following POST request:
---- HTTP REQUEST ----
POST https://appleid.apple.com/auth/token
Headers:
Content-Type: application/x-www-form-urlencoded
Body:
client_id=au.com.thejlrguy.businesschat&client_secret=eyJhbGciOiJFUzI1NiIsImtpZCI6IktLUDc4MkhGVTcifQ.eyJ...QeDn7ug&grant_type=client_credentials&scope=https%3A%2F%2Fappleid.apple.com
Getting the below error:
{"error":"invalid_client"}
The private key used to sign the JWT was created 24 hours ago.
You are probably aware of the upcoming root certificate change for any servers you might have that you use to send push notifications by connection to APNs.
If you are not, here is the announcement.
We have been getting some questions about this, and understand not everyone is familiar with their server setup.
First, we would like to clarify that this is only a change to your server's certificate trust store. You do not need to update anything else, like your APNs push certificates, the build certificates and provisioning profiles for your team/app, and so on. All you need to do is to install the mentioned new root certificate to your push server's trust store.
If you are using a 3rd party push provider, it is them who will need to handle their servers. But you may want to double check with them nevertheless.
If you are managing your own push servers that connect to APNs directly, then it is your responsibility to download and install the root certificate mentioned in the above link on your server(s).
Unfortunately we cannot provide specific instructions on how to install this root certificate on every kind of server out there. Each server operating system/push server software will have different ways these root certificates are installed, which is out of scope of our support abilities.
If you are not sure how to do this, I would recommend you seek help for this from your server-side developers or server admins.
Or, if you don't have access to such resources, you can ask the support channels for your system the question: How do I install a root certificate?
We have setup a test server at 17.188.143.34:443 that you can use to try and send pushes to test whether your new root certificate is correctly installed.
An alternative way to test this would be, from a terminal prompt:
openssl s_client -connect 17.188.143.34:443 -servername api.sandbox.push.apple.com -verifyCAfile USERTrustRSACertificationAuthority.crt -showcerts
Change the parameter to the -verifyCAfile argument to point to your trust store, and it should allow you to validate
Sample return results would be:
Connecting to 17.188.143.34
CONNECTED(00000003)
depth=2 C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority
verify return:1
depth=1 CN=Apple Public Server RSA CA 11 - G1, O=Apple Inc., ST=California, C=US
verify return:1
depth=0 C=US, ST=California, O=Apple Inc., CN=api.sandbox.push.apple.com
verify return:1
Argun Tekant /
DTS Engineer /
Core Technologies
Topic:
App & System Services
SubTopic:
Notifications
Tags:
APNS
User Notifications
PushKit
Push To Talk
I wanted to know if Apple ever supported displaying a red dot on notificationswith no indication number.
Topic:
App & System Services
SubTopic:
Notifications
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
I have set up an iOS application with CarPlay scene using carplay-driving-tasks entitlement. And as per latest policy changes I'm able to get push notifications in the CarPlay screen. But unlike from phone scene, when I tap on a notification from CarPlay I don't get a trigger on didReceive method to intercept the payload of the notification that user tapped on. Is there any other ways or configuration needed to get this working?
I just need to get the payload and present an Alert template within the CarPlay when user taps on a CarPlay notification and the app opens.
Topic:
App & System Services
SubTopic:
Notifications
Tags:
APNS
CarPlay
Notification Center
User Notifications
self.pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
self.pushRegistry.delegate = self;
self.pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
//处理接收到的VoIP推送
(void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void(^)(void))completion
then we send message from our server or from apple's cloud service: https://icloud.developer.apple.com/dashboard/notifications website services:
when app is in foreground,withCompletionHandler wil be called correctly,but when app is in background or has killed ,withCompletionHandler not be called!!!
the background fetch、voice over ip is checked in signing & capabilities tabs
why?why?why?why?why?why?why?why?why?
Hello,
We are trying to implement Actionable Notifications on iOS via Remote Notifications.
According to Apple’s official documentation (Declaring Your Actionable Notification Types),
it is recommended to register notification categories at launch time.
However, in our use case, the number of buttons and their actions in the Actionable Notification are determined at the time of the Remote Notification request.
This means that we cannot predefine the categories at app launch but need to dynamically configure them based on the payload of the Remote Notification.
Our Approach
We are considering setting aps.mutable-content = 1 and using Notification Service Extension to modify the categoryIdentifier dynamically.
Below is the JSON payload we plan to use for Remote Notifications:
{
"aps": {
"alert": {
"title": "New Message Received!",
"body": "Check out the details."
},
"category": "DYNAMIC_CATEGORY",
"mutable-content": 1
},
"categoryData": {
"id": "DYNAMIC_CATEGORY",
"actions": [
{
"id": "REPLY_ACTION",
"title": "Reply",
"options": ["foreground"]
},
{
"id": "DELETE_ACTION",
"title": "Delete",
"options": ["destructive"]
}
]
}
}
Questions:
Can we dynamically configure Actionable Notifications based on the Remote Notification payload?
If we set categoryIdentifier in Notification Service Extension’s didReceive(_:withContentHandler:), will users still see the correct action buttons even if the app is terminated?
What is the recommended approach to dynamically configure Actionable Notifications at the time of receiving the Remote Notification, rather than at app launch?
Our mobile app uses a specific platform for subscription management. At this time,, it's integration with Apple notifications is built around the Server-to-Server Notifications v1 and the traditional verifyReceipt endpoint. At this time, it does not support Server-to-Server Notifications v2, nor has any published documentation or resources on a custom integration path using v2.
Our app is built using Flutter and we handle purchases with the in_app_purchase plugin. However, due to the limitation on the system for subscription side, we need to connect to Apple’s legacy server-to-server subscription endpoints (StoreKit v1) to receive real-time notifications and validate receipts. Could you please provide information how to do it?
Topic:
App & System Services
SubTopic:
Notifications
I’m getting calls from Pakistan every hour. I cant block them because it’s a different number every time. I have downloaded the new beta version of the upcoming software update and it allows you to set to ask a question before unknown callers ring through. It’s not working and my phone is constantly ringing. I can’t block unknown callers as I use my phone for work. How can I silence ringing from calls specifically from Pakistan Using the country code?
Topic:
App & System Services
SubTopic:
Notifications
Hi Apple team,
We’re shipping a Live Caller ID Lookup extension on iOS 18 and have a question about the automatic refresh of configuration/PIR parameters.
Questions
1. Is there any documented interval/TTL (min/max) for the system’s automatic refresh of /config and PIR parameters, or is it entirely opportunistic (battery/network/usage)? I can’t find a cadence in the IdentityLookup docs.
2. Does iOS honor server cache headers (e.g., Cache-Control/Expires) to influence when it re-fetches?
3. Which events also trigger a refresh (enable/disable in Settings, OS/app update, device reboot, token/epoch change)?
4. Are there rate limits or best-practice limits for calling refreshExtensionContext and refreshPIRParameters?
Topic:
App & System Services
SubTopic:
Notifications
Tags:
Extensions
SMS and Call Reporting
CallKit