I've added a Notification Service Extension as a target to my React Native iOS app following Apple's official documentation. After completing all the setup steps as outlined in the documentation, the notification titles remain unchanged - notifications are arriving without any modifications, suggesting the extension isn't functioning properly.Testing Details:
Sending notifications via Apple Push Notification Console
Tested on iPhone 16 Pro Max (physical device)
Tested on iPhone 15 Pro simulator
Both show the same issue - no title modifications
The extension appears to not be executing at all. Has anyone encountered similar issues with Notification Service Extensions in React Native projects, or can suggest troubleshooting steps to verify the extension is properly configured and running?
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
Hello everyone.
I'm trying to add a lifetime for push notifications via apns-expiration for my application.
With the Internet turned on, push notifications come, that's ok.
With the Internet turned off, as I noticed, only the last push with the badge installation on the application icon comes.
That is, the logic is that a text push with text is sent, then after N time the next push to the same device with the badge installation.
I would like to receive a text push after turning on the Internet.
Topic:
App & System Services
SubTopic:
Notifications
Hi, I’m having issues with push notifications on my phone across multiple apps. When someone sends me a message, I only receive the notification 10 to 15 minutes later. For example, on WhatsApp, people say that my chat only shows one checkmark when they send me a message.
I don’t know what else to do. I’ve already contacted Apple Support, visited an Apple-affiliated physical store, and followed all the recommended procedures. This is my first time using an iPhone—I bought it for professional use, but it’s practically useless if I don’t receive notifications instantly.
They even told me that if I send it in for warranty service, there’s a 90% chance they won’t detect the issue, and the iPhone will come back with the same problem.
The iOS documentation shows notification actions buttons with the text center aligned: https://developer.apple.com/documentation/usernotifications/declaring-your-actionable-notification-types
But there's no apparent way for an app to control this. The buttons are controlled and rendered by the system and the text is always left aligned.
Is there some way to get the text center aligned?
I have been watching the following moment from wwdc (Design dynamic Live Activities):
https://developer.apple.com/videos/play/wwdc2023/10194/?time=728
It suggest that you should 'tick' between multiple live activities of your app:
When you want to show multiple sessions for your app going on at once, consider ticking between the display of them to continue to give users an eye on everything that’s going on.
How can I tick between them? More specifically how can I do that when my app is in the background?
Is there any callback available when a/all notifications is/are removed from notification tray?
I've built an iOS & Watch OS app using Sign in with Apple & CloudKit exclusively.
I'm now wanting to implement Push Notifications. I understand that I need a server to trigger the push notifications (I guess I could spool up a Node server somewhere or use Firebase), but I'd really like to not use any non-Apple backend services.
Am I correct in understanding that I can do this with Push Notifications Console, or do I still need a separate backend?
when I implementation the UNUserNotificationCenterDelegate
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
var status = ""
if (UIApplication.shared.applicationState == .active) {
status = "active"
} else if (UIApplication.shared.applicationState == .background) {
status = "background"
} else if (UIApplication.shared.applicationState == .inactive) {
status = "inactive"
}
completionHandler()
}
I find that UIApplication.shared.applicationState == .background this case can not execute when application is in background。
why applicationState is inactive not background?
I got notification filtering permission from appStoreConnect, i.e. com.apple.developer.usernotifications.filtering, but not able to suppress notification even after setted contentHandler(UNNotificationContent()) and contentHandler(UNMutableNotificationContent()).
Added entitlements in both extension and main app, also in signing profile these Entitlements are visible, what other changes should I do?
Topic:
App & System Services
SubTopic:
Notifications
Provisioning profiles created for my App ID are not including the Push Notifications capability, even though Push Notifications is enabled in the App ID configuration in Apple Developer Portal.
I have enabled Push Notifications for my App ID (com.abc.app) in the Apple Developer Portal. The capability shows as enabled and saved. However, when provisioning profiles are generated (either manually or through third-party tools like Expo Application Services), they do not include:
The Push Notifications capability
The aps-environment entitlement
This results in build failures with the following errors:
Provisioning profile "*[expo] com.abc.app AppStore [timestamp]" doesn't support the Push Notifications capability.
Provisioning profile "*[expo] com.abc.app AppStore [timestamp]" doesn't include the aps-environment entitlement.
Steps Taken
✅ Enabled Push Notifications in App ID configuration (com.mirova.app)
✅ Saved the App ID configuration multiple times
✅ Waited for Apple's systems to sync (waited 5-10 minutes)
✅ Removed and re-added Push Notifications capability (unchecked, saved, re-checked, saved)
✅ Created Push Notification key in Apple Developer Portal
✅ Verified Push Notifications is checked and saved in App ID
❌ Provisioning profiles still created without Push Notifications capability
Expected Behavior
When Push Notifications is enabled for an App ID, any provisioning profiles created for that App ID should automatically include:
Push Notifications capability
aps-environment entitlement (set to production or development)
Actual Behavior
Provisioning profiles are created without Push Notifications capability, even though:
Push Notifications is enabled in App ID
App ID configuration is saved
Sufficient time has passed for sync
Additional Information
Push Notification Key: Created and valid (Key ID: 3YKQ7XLG9L and 747G8W2J68)
Distribution Certificate: Valid and active
Provisioning Profile Type: App Store distribution
Third-party Tool: Using Expo Application Services (EAS) for builds, but issue persists with manually created profiles as well
Questions
Is there a delay or sync issue between enabling Push Notifications in App ID and it being available for provisioning profiles?
Are there any additional steps required to ensure Push Notifications is included in provisioning profiles?
Is there a known issue with Push Notifications capability not being included in provisioning profiles?
Should I create the provisioning profile in a specific way to ensure Push Notifications is included?
Environment
Platform: iOS
Build Type: App Store distribution
Xcode Version: (via EAS cloud build)
Thank you for your assistance. I've been unable to resolve this issue and would appreciate any guidance.
iOS Deployment Target: Latest
While click on notification tray I do not want to open my ticket.
I created a Notification Service Extension to display profile images in place for the app image (i.e. iMessage).
I send a remote push notification via Firebase Functions, and in the payload, the relevant profile image url string. The profile image url string in the payload is successfully delivered as it appears in my console log and AppDelegate didReceiveRemoteNotification function.
My problem is the profile image does not replace the default app icon image in the remote push notification.
Below is my configuration. Any guidance would be appreciated!
Main target app: the info plist contains NSUSerActivityTypes = [INSendMessageIntent]. The Communications Notifications capability is enabled and "Copy only when installing" in Build Phases Embed Foundation Extensions
Notification Service Extension plist: contains NSExtension > NSExtensionAttributes > IntentsSupported > INSendMessageIntent.
Notification Service Extension class code:
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
guard var bestAttemptContent = bestAttemptContent else { return }
guard let fcmOptions = bestAttemptContent.userInfo["fcm_options"] as? [String: Any],
let attachmentUrlAsString = fcmOptions["imageURL"] as? String else {
contentHandler(bestAttemptContent)
return
}
if let attachmentUrl = URL(string: attachmentUrlAsString) {
var senderNameComponents = PersonNameComponents()
senderNameComponents.nickname = bestAttemptContent.title
let profileImage = INImage(url: attachmentUrl)
let sender = INPerson(personHandle: INPersonHandle(value: "1233211234", type: .unknown), nameComponents: senderNameComponents, displayName: bestAttemptContent.title, image: profileImage, contactIdentifier: nil, customIdentifier: nil, isMe: false)
let receiver = INPerson(personHandle: INPersonHandle(value: "1233211234", type: .unknown), nameComponents: nil, displayName: nil, image: nil, contactIdentifier: nil, customIdentifier: nil, isMe: true)
let intent = INSendMessageIntent(
recipients: [receiver],
outgoingMessageType: .outgoingMessageText,
content: "Test",
speakableGroupName: INSpeakableString(spokenPhrase: "Sender Name"),
conversationIdentifier: "sampleConversationIdentifier",
serviceName: nil,
sender: sender,
attachments: nil
)
intent.setImage(profileImage, forParameterNamed: \.sender)
let interaction = INInteraction(intent: intent, response: nil)
interaction.direction = .incoming
interaction.donate(completion: nil)
if #available(iOSApplicationExtension 15.0, *) {
do {
bestAttemptContent = try bestAttemptContent.updating(from: intent) as! UNMutableNotificationContent
} catch {
contentHandler(bestAttemptContent)
return
}
}
contentHandler(bestAttemptContent)
} else {
contentHandler(bestAttemptContent)
return
}
}
}
Having some discussion about when we should clear out a token from our servers.
Docs say:
Don’t retry notification responses with the error code BadDeviceToken, DeviceTokenNotForTopic, Forbidden, ExpiredToken, Unregistered, or PayloadTooLarge. You can retry with a delay, if you get the error code TooManyRequests.
The way I see it is that with the exception of PayloadTooLarge, all other errors means you should remove the token from your server. Either because:
The token is no longer good
The token is good, but this is just not the right:
environment (sandbox vs production)
topic (the token is from a different bundle id or developer team)
target (app vs live activity appex)
Do I have it right?
Extra context: when using the "JSON Web Token Validator" tool, a colleague reported that a 410 -Expired token (from couple days back) was still valid today. This raises questions about when tokens should actually be deleted and how these error codes should be interpreted.
Also is it possible for the docs to get updated for us to explicitly know if a token should get removed and not leave it for interpretation?
Hi there, we noticed high volume of 410 responses from APNs.
It started on July 19th and we see it across multiple apps. Is there some sort of mass token invalidation/removal that's happening on APNs?
How to create a Notifications Settings button in the Notification Settings similar to Facebook Notification Settings that will lead users to the app's internal settings page?
Topic:
App & System Services
SubTopic:
Notifications
Hello Everyone,
I somehow missed to renew the APNS Certificate,
I am new to Apple Ecosystem, I can not see the expired or any Certificates under
Certificates, Identifiers & Profiles
Can anyone help me with this!
Hello,
We are facing issue that sometimes a voip notification gets delivered after it is expired. The issue can be simply demonstrated we set the device to flight mode, and after 20s we disable flight mode. We still receive the voip notification.
We are setting the expiration header as following apns-expiry=0, so from my understanding it should not be delivered if the device was not able to receive the notification in the fist attempt.
I have read following thread https://developer.apple.com/forums/thread/778512, from which I understand this is a long standing issue.
Hence my question is, is there any way how we can notify the call kit that the call is actually no longer valid, and do not display the call to the user at all?
Currently we are forced to always display CallKit call when the notification comes, and some of our users are confused that they see a missed call which they did not have any chance to pick up.
Please let me know if you need any more information.
Best Regards,
Adam Chlupacek
Dear Apple Engineer
Recently we found that our push delivery rate has decreased. On the website "https://icloud.developer.apple.com/dashboard/notifications/teams/43Y657P48S/app/com.taobao.fleamarket", we found that starting from January 8, 2025, "Discarded - Token Unregistered" showed an upward trend, from millions to tens of millions.
We have not found the reason, and hope you can help us.
Team ID: 43Y657P48S
Bundle ID: com.taobao.fleamarket
Here are some failed tokens, in "Device Token Validator" The query is valid, but the user cannot receive the message:
56025f656cc3aa701898037f59e8d0cb937263ff5585cd1cec9ae661dcc15b19
5fbbd1e604d3662d7583e9377676f8fa276005145278d6dea04b4fc85a7b070e
f0970602551f8d249d8f97960a74006ad78688b52fec6b0d19a585 207caff62e 9388fb40209c100afc2db728342f6fe86c7e34787a8fe4a92b73d2503c5286e0 a2819a4708462588b07452ed827d9afb03c343b586e70dcb67a9981f76295704 8949373cd43783fa3e23d38d55ee1fd72475b39f9c2d2fedca3ecb925b094240
Best Regards!
I'm attempting to leverage notifications in an app that is in Swift 6 language mode. I have the following code:
func startLocationUpdates() {
//if self.manager.authorizationStatus == .notDetermined {
// self.manager.requestWhenInUseAuthorization()
//}
self.logger.info("Starting location updates")
Task {
do {
let updates = CLLocationUpdate.liveUpdates()
for try await update in updates {
if !self.updatesStarted { break } // End location updates by breaking out of the loop.
self.lastUpdate = update
if let loc = update.location {
self.lastLocation = loc
self.isStationary = update.stationary
self.count += 1
self.logger.info("Location \(self.count): \(self.lastLocation)")
}
if lastUpdate!.insufficientlyInUse {
let notification = UNNotificationRequest(identifier: "com.example.mynotification", content: notificationContent, trigger: nil)
try await UNUserNotificationCenter.current().add(notification)
}
}
} catch {
self.logger.error("Could not start location updates")
}
return
}
}
As an aside, the above is directly taken from the following sample:
https://developer.apple.com/documentation/CoreLocation/adopting-live-updates-in-core-location.
With Swift 6 language mode enable, this generates a compiler error for the statement:
try await UNUserNotificationCenter.current().add(notification)
Sending main actor-isolated 'notification' to nonisolated instance method 'add' risks causing data races between nonisolated and main actor-isolated uses
How can I fix this?
Topic:
App & System Services
SubTopic:
Notifications
This is in an iOS Simulator running iOS 18.2
I send a start live activity push notification from the Push Notifications Console on icloud.developer.apple.com. When checking the console.log output it seems to receive the message, yet the activity does not appear in the dynamic island. (the app is backgrounded when I test this)
Can anyone tell me why it's not showing? Starting the same activity from within the app using Swift code works fine.
Here is the console.app output:
default 11:01:59.060954+0100 apsd <APSConnectionServer: 0x104207b80; development/com.apple.aps.sessioncore.PushNotifications.dev/liveactivitiesd 0>: Sending push to client. UUID: (null)
default 11:01:59.061012+0100 apsd Dispatching high priority message on server: <APSConnectionServer: 0x104207b80; development/com.apple.aps.sessioncore.PushNotifications.dev/liveactivitiesd 0>
default 11:01:59.061770+0100 apsd Looking up connection on peer: 4304b50 found <APSConnectionServer: 0x104207b80; development/com.apple.aps.sessioncore.PushNotifications.dev/liveactivitiesd 0>
default 11:01:59.062283+0100 liveactivitiesd APSXPCDeliverMessageEvent: Created APSIncomingMessage. UUID: (null)
default 11:01:59.062642+0100 liveactivitiesd <APSConnection: 0x600003d18000> Delivering message from apsd: <APSIncomingMessage: 0x600000c2e9a0> 2897852514 com.****.****.push-type.liveactivity
default 11:01:59.062763+0100 liveactivitiesd <APSConnection: 0x600003d18000> Delivering message from apsd. UUID: (null)
default 11:01:59.063374+0100 liveactivitiesd <APSConnection: 0x600003d18000> making delegate (<SessionPushNotifications.APSPushConnection: 0x600000227460>) calls to deliver message 2897852514 {
aps = {
alert = {
"loc-key" = "recording_started_message";
"title-loc-key" = "recording_started_title";
};
attributes = {
isRecording = 1;
};
"attributes-type" = SWAutomaticTripRecorderActivityAttributes;
"content-state" = {
distance = 0;
};
event = start;
timestamp = 1742374701;
};
} for topic com.****.****test.push-type.liveactivity
default 11:01:59.063440+0100 liveactivitiesd <APSConnection: 0x600003d18000> calling <SessionPushNotifications.APSPushConnection: 0x600000227460> connection:didReceiveIncomingMessage:
default 11:01:59.063740+0100 liveactivitiesd Acquiring keep-alive with reason: Received message
default 11:01:59.063785+0100 liveactivitiesd Keep-alive reasons: ["Received message": 1]
default 11:01:59.063803+0100 liveactivitiesd <APSConnection: 0x600003d18000> returned from <SessionPushNotifications.APSPushConnection: 0x600000227460> connection:didReceiveIncomingMessage:
default 11:01:59.063883+0100 liveactivitiesd <APSConnection: 0x600003d18000> responding with an ack for message with guid E19D7D04-12A0-4F1B-B33C-F6BF57EE2EFF
default 11:01:59.063921+0100 liveactivitiesd <APSConnection: 0x600003d18000> responding with an ack. UUID: (null)
default 11:01:59.063996+0100 apsd Looking up connection on peer: 4304b50 found <APSConnectionServer: 0x104207b80; development/com.apple.aps.sessioncore.PushNotifications.dev/liveactivitiesd 0>
default 11:01:59.064019+0100 apsd <APSUserCourier 0x100f052a0 development 0> informed that <APSConnectionServer: 0x104207b80; development/com.apple.aps.sessioncore.PushNotifications.dev/liveactivitiesd 0> acknowledges incoming message with guid E19D7D04-12A0-4F1B-B33C-F6BF57EE2EFF tracingUUID (null)
default 11:01:59.064063+0100 liveactivitiesd Received message: topic: Topic(unsuffixed: "com.****.****test"); channelID: nil; token: Optional(128 bytes); eventType: start(SessionPushNotifications.IncomingMessage.EventType.StartParameters(attributesType: "SWAutomaticTripRecorderActivityAttributes", attributesData: 20 bytes, inputs: [])) for environment: development
default 11:01:59.064198+0100 liveactivitiesd Received push event for com.****.****test::pushToStart
default 11:01:59.064232+0100 liveactivitiesd Adding push-to-start budget for com.****.****test::pushToStart
default 11:01:59.064273+0100 liveactivitiesd Acquiring keep-alive with reason: Database
default 11:01:59.064296+0100 liveactivitiesd Keep-alive reasons: ["Database": 1, "Received message": 1]
default 11:01:59.064313+0100 liveactivitiesd Acquiring keep-alive with reason: Database
default 11:01:59.064330+0100 liveactivitiesd Keep-alive reasons: ["Database": 2, "Received message": 1]
default 11:01:59.064342+0100 liveactivitiesd Reduced budget for com.****.****test::pushToStart to: 9
default 11:01:59.064358+0100 liveactivitiesd Topic com.****.****test.push-type.liveactivity has remaining budget for pushToStart of 9
default 11:01:59.064369+0100 liveactivitiesd Topic com.****.****test.push-type.liveactivity has not used any budget for activity
default 11:01:59.064436+0100 liveactivitiesd Scheduling wake to re-evaluate push subscription budgets at 2025-03-19 11:01:59 +0000
default 11:01:59.064547+0100 liveactivitiesd Earliest nonwaking date from task "Push server budget timeout expiration": 2025-03-19T12:01:59+01:00, finalWakeTarget: 2025-03-19T12:01:59+01:00 3599.999696
default 11:01:59.064593+0100 liveactivitiesd Earliest waking date from task "Push server budget timeout expiration": 2025-03-19T12:01:59+01:00, finalWakeTarget: 2025-03-19T12:01:59+01:00 3599.999651
default 11:01:59.064620+0100 liveactivitiesd Scheduling nonwaking task for: 2025-03-19T12:01:59+01:00 in 3599.999622s
default 11:01:59.064659+0100 liveactivitiesd Scheduling waking task for: 2025-03-19T12:01:59+01:00 in 3599.999584s
default 11:01:59.064671+0100 liveactivitiesd Acquiring keep-alive with reason: wake scheduling
default 11:01:59.064692+0100 liveactivitiesd Keep-alive reasons: ["Database": 2, "Received message": 1, "wake scheduling": 1]
default 11:01:59.064734+0100 liveactivitiesd Scheduling waking task for adjusted date: 2025-03-19T12:01:59+01:00 in 3599.999508s
default 11:01:59.064768+0100 liveactivitiesd xpc_activity_register: com.apple.sessionkit.wake, criteria: dictionary
default 11:01:59.064843+0100 liveactivitiesd Received pushToStart notification for com.****.****test::pushToStart
default 11:01:59.064955+0100 liveactivitiesd Keep-alive reasons: ["Database": 2, "Received message": 1]
default 11:01:59.064979+0100 liveactivitiesd Publishing event: timestamp: 2025-03-19 08:58:21 +0000; activityIdentifier: F432AB2F-1799-4437-B54B-6D9D70A0B260; eventType: start(SessionPushNotifications.PushEvent.EventType.ActivityStartParameters(attributesType: "SWAutomaticTripRecorderActivityAttributes", attributesData: 20 bytes, contentSourceRequests: [ActivityKit.ActivityContentSource.Request.push(request: ActivityKit.PushActivityContentSource.Request.push, target: ProcessDescriptor.Request("com.****.****test")), ActivityKit.ActivityContentSource.Request.process(target: ProcessDescriptor.Request("com.****.****test"))]))