I'm trying to rewrite a Swift code to Swift 6 language mode and am stuck with this problem. How do I safely pass the bestAttemptContent and contentHandler to the Task? This is from the UNNotificationServiceExtension subclass.
final class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
var customNotificationTask: Task<Void, Error>?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
guard let bestAttemptContent = bestAttemptContent else {
invokeContentHandler(with: request.content)
return
}
do {
let notificationModel = try PushNotificationUserInfo(data: request.content.userInfo)
guard let templatedImageUrl = notificationModel.templatedImageUrlString,
let imageUrl = imageUrl(from: templatedImageUrl) else {
invokeContentHandler(with: bestAttemptContent)
return
}
setupCustomNotificationTask(
imageUrl: imageUrl,
bestAttemptContent: bestAttemptContent,
contentHandler: contentHandler
)
} catch {
invokeContentHandler(with: bestAttemptContent)
}
}
// More code
private func downloadImageTask(
imageUrl: URL,
bestAttemptContent: UNMutableNotificationContent,
contentHandler: @escaping (UNNotificationContent) -> Void
) {
self.customNotificationTask = Task {
let (location, _) = try await URLSession.shared.download(from: imageUrl)
let desiredLocation = URL(fileURLWithPath: "\(location.path)\(imageUrl.lastPathComponent)")
try FileManager.default.moveItem(at: location, to: desiredLocation)
let attachment = try UNNotificationAttachment(identifier: imageUrl.absoluteString, url: desiredLocation, options: nil)
bestAttemptContent.attachments = [attachment]
contentHandler(bestAttemptContent)
}
}
}
I tried using the MainActor.run {}, but it just moved the error to that run function.
The UNNotificationRequest is not sendable, and I don't think I can make it so.
Wrap the setupCustomNotification in a Task will move the errors to the didReceive method.
It seems like the consuming keyword will help here, but it leads to a compilation error, even with the latest Xcode (16.2).
Any pointers?
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
i got some problem for the LiveAcitvity when i start it with notification.
The LiveActivity can not show,but it can work when i update or end a LiveActitvity;
And so,i think my configeration is right like the code;
thanks in advance
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
From iPhone iOS 18.3 , 18.3.1, and 18.4 Dev2, VIP Mail alerts will not wake a phone display to notify of a new mail received for a VIP contact. The phone will sound an audible tone indicating the mail was received, and if you manually wake the screen by tapping and then dragging upward to show notifications you will then see the VIP mail alert. However if the screen is sleeping, it will not light up or wake to indicate or display the new mail.
The problem was briefly resolved in 18.4 Dev1, but problem returns in Dev2. We see this across all iPhone 16 Pros and iPhone SE2 with iOS 18.3 or higher. Is this something acknowledged by Apple as on track for resolution in iOS 18.4 Final Release? Thank you.
Topic:
App & System Services
SubTopic:
Notifications
Observations:
When our app calls the APNs API for push notifications, we observed significant fluctuations:
July 15-25: The success response volume increased by 20% compared to the baseline before July 15.
After July 25: Success rates returned to baseline levels.
July 30: Success response volume decreased by 10% compared to the pre-July 15 baseline.
Excluded Factors:
No changes in target audience size or characteristics (business factors ruled out).
Server logs confirm consistent API request parameters and frequency.
Key Questions:
Were there any adjustments to response metrics (e.g., success status code definitions) during this period?
Have other developers reported similar issues?
Were there server-side configuration updates or known incidents on Apple’s end?
Topic:
App & System Services
SubTopic:
Notifications
Tags:
APNS
App Store Server Notifications
User Notifications
After updating to iOS 26 beta 1, I can't receive any push notifications from most applications.
I can receive notifications from like Calendar, which uses local & reserved notifications, but I can't receive any remote-based notifications.
Topic:
App & System Services
SubTopic:
Notifications
In the main app, is there a way to distinguish whether the application:didFinishLaunchingWithOptions: method is triggered by the user manually clicking the app icon, or whether it is automatically triggered by the system after Live Activities receives a remote message notification?
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?
Hi Apple Dev Team,
We have a React Native application that includes call functionality using PushKit and VoIP notifications.
We are using APNS to send the VoIP notifications, and everything has been working smoothly on iOS versions up to 18.3.1.
However, after updating to iOS 18.4, we are no longer receiving incoming VoIP push notifications on the device.
There have been no code changes related to our PushKit or notification logic — the exact same build continues to work correctly on devices running iOS 18.3.1 and earlier.
We're trying to understand if anything has changed in iOS 18.4 that affects VoIP push delivery or registration behavior.
Would appreciate any guidance, and happy to share code snippets or configuration if needed.
Thanks in advance!
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.
I am sending push notification using HTTP/2 to https://api.push.apple.com:443 api but I am getting Operation TimeOut error in response . Can someone help
Do we need this new certificate "SHA-2 Root : USERTrust RSA Certification Authority certificate" if we are using token based authentication with APNs? We are signing the JWT with the private Auth key?
Or is the new certificate needed on top of this?
We are doing something like this:
Dictionary<string, object> payload = new Dictionary<string, object>()
{
{ "iss", teamId }, // Apple Developer Team ID
{ "iat", unixTimestamp } // Issued-at time
};
Dictionary<string, object> header = new Dictionary<string, object>()
{
{ "alg", "ES256" },
{ "kid", keyId } // Key ID from Apple Developer portal
};
string token = JWT.Encode(payload, privateKey, JwsAlgorithm.ES256, header);
My Mac app has a launch agent (within the app bundle) that works great without the app running. There are some occasions where I need to display an alert and ask the user to launch the app to handle the issue. I thought about using UNUserNotificationCenter but I'm not able to make it work from the agent.
I'm asking for authorization as follows:
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
NSLog(@"authorization request completion. Granted: %@, error: %@ (%@)",granted?@"YES":@"NO",error, [error localizedDescription]);
}];
And I'm trying to post the notification as follows:
content.title = @"Your App Name";
content.body = @"Click the button to open the app";
content.sound = [UNNotificationSound defaultSound];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:[[NSUUID UUID] UUIDString]
content:content
trigger:nil];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (error) {
NSLog(@"Error showing notification: %@ %@", error, [error localizedDescription]);
}
}];
When running I'm getting asked to authorize, I authorize and all seems OK in system settings but I'm not able send any notifications. addNotificationRequest results in UNErrorCodeNotificationsNotAllowed error.
I tried this with the authorization request inside the main app, or inside the agent, with the same results.
When trying to post the notification from within the app, it does work, but that's not what I need.
Is posting notifications from within the launch agent not possible at all, or is there anything here that I'm missing.
TIA
I'm having trouble displaying the Apple Wallet pass logo on iOS 18 when a notification occurs. It works on iOS 17 but not on iOS 18 (tested on versions 18.1 and 18.3).
I ensured the Wallet pass icon sizes are correct:
icon.png → 29×29
icon@ 2x.png → 58×58
icon@ 3x.png → 87×87
Questions:
Has Apple changed any requirements for displaying Wallet pass logos in iOS 18?
Are there new size, format, or metadata constraints?
iOS has a feature that suppresses or limits the display of push notifications when multiple notifications are sent in quick succession (often referred to as rate limiting or filtering). Specifically, how many notifications within what timeframe might trigger such suppression?
Topic:
App & System Services
SubTopic:
Notifications
I am trying to retrieve delivered notifications using UNUserNotificationCenter.getDeliveredNotifications(completionHandler:), but I have encountered an issue:
Notifications triggered by UNTimeIntervalNotificationTrigger or UNCalendarNotificationTrigger appear in the delivered list.
However, notifications triggered by UNLocationNotificationTrigger do not appear in the list.
Here is the code I use to fetch delivered notifications:
UNUserNotificationCenter.current().getDeliveredNotifications { notifications in
for notification in notifications {
print("Received notification: \(notification.request.identifier)")
}
}
The notification is scheduled as follows:
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Test Notification"
content.body = "This is a location-based notification."
content.sound = .default
let coordinate = CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194) // Example coordinates
let region = CLCircularRegion(center: coordinate, radius: 100, identifier: "TestRegion")
region.notifyOnEntry = true
region.notifyOnExit = false
let trigger = UNLocationNotificationTrigger(region: region, repeats: false)
let request = UNNotificationRequest(identifier: "LocationTest", content: content, trigger: trigger)
center.add(request) { error in
if let error = error {
print("Error adding notification: \(error.localizedDescription)")
}
}
Why does getDeliveredNotifications not return notifications that were triggered using UNLocationNotificationTrigger?
How can I retrieve such notifications after they have been delivered?
PLATFORM AND VERSION: iOS
Development environment: Other: .net MAUI with vscode
Run-time configuration: iOS 18.1.1
DESCRIPTION OF PROBLEM
APNS notifications of apns-push-type pushtotalk sometimes stop arriving after switching networks.
STEPS TO REPRODUCE
We have created a simple app which can be used to deminstrate this issue. When you launch the app it displays the APNS token which you can then use fromn the Apple Push Console to manually send it PTT push notifications.
https://github.com/trampster/PttPushNotificationIssue
On an iPhone SE (we havn't been able to reproduce on our iPhone 11)
Start the APP to register for the APNS push notifications
Turn off the WiFi wait for 5 seconds
Attempt a push to the app manually using the Push Notifications Console (this should fail, which is fine)
Turn on Cellular and wait for it to connect
Attempt to push to the app manually using the Push Notifications Console
-> This fails, and all attempts to send an pushtotalk push notifications fail until the we switch network again.
Send a push while offline before connecting to the new network seems to make it happen more often but hard to tell for sure.
The results of the failed push in the console look like this:
Delivery LogLast updated: 30/01/25, 16:45:06 GMT+13 Refresh
30 Jan 2025, 16:45:03.661 GMT+13
received by APNS Server
30 Jan 2025, 16:45:03.662 GMT+13
discarded as device was offline
The device is actually very much online.
Switching networks again oftern makes things come right. But it doesn't seem to come right by itself.
We can't respond to network changes and do anything as the whole point of using push-to-talk push notifications is to wake up the app when in the background to answer a call, this means we are not running and therefore cannot respond to network changes to try to work arround this issue.
I am trying to issue the "start" APNs push notification to start a live activity for my iOS app. The notification appears to send correctly, there is no error message, but the live activity never appears for any of my users (users are in TestFlight).
In addition to issuing the APNs commands from my server, I have also tried using the CloudKit Push Notification Console to manually generate a "start" notification. It submits correctly but the live activity never starts.
I have also checked the Console app to watch the device logs and see if iOS is rejecting/throttling the live activity but I don't see any activity related to the start message at all.
Here are some details:
App bundle ID: `com.penzu.moodmoji`
APNs topic: `com.penzu.moodmoji.push-type.liveactivity`
APNs push type: `liveactivity`
Recent apns-id: `7b633309-b7fd-4163-b620-776efa04f315`
APNs payload:
{
"aps": {
"timestamp": 1742651625,
"event": "start",
"content-state": {
"totalDays": 7,
"currentDay": 2,
"progress": 0.29,
"status": "ACTIVE",
"reportReady": false
},
"attributes-type": "GoalActivityAttributes",
"attributes": {
"totalDays": 7,
"currentDay": 2,
"progress": 0.29,
"status": "ACTIVE",
"reportReady": false
},
"alert": {
"title": "It's day 2!",
"body": "Don't forget to record every time you feel anxious today."
}
}
}
I can confirm that LiveActivities started by the iOS app with ActivityKit work correctly, and the app does appear to be receiving pushToStartTokenUpdates:
struct GoalActivityAttributes: ActivityAttributes, Sendable {
struct ContentState: Codable & Hashable, Sendable {
let totalDays: Int
let currentDay: Int
let progress: Double
let status: String
let reportReady: Bool
}
let goal: SimpleGoal
}
for await nextStartToken in Activity<GoalActivityAttributes>.pushToStartTokenUpdates {
// send nextStartToken to server...
}
The app I'm testing with is in TestFlight, using the production APNs environment.
When I turn the Ringtone and Alerts volume all the way up, I expect standard notifications to play at the loudest level the device allows. In theory, this should match the volume of a critical alert with its sound.volume set to 1.0 in payload.
However, I’ve noticed that non-critical notifications still play quieter than critical alerts under these conditions. Critical alerts with volume: 1.0 sound noticeably louder than standard notifications, even though the Ringtone and Alerts slider is already set to maximum. And I couldn't find a documentation for this behavior anywhere.
Is this expected behavior on iOS? And is there any way to make non-critical notifications play at the same maximum loudness as critical alerts?
Thanks in advance for any clarification.
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
}
}
}