Hi,
since at least yesterday api.sandbox.push.apple.com is not available.
It was working before, but now it seems the domain can't be resolved.
I tried nslookup in the terminal.
nslookup api.sandbox.push.apple.com
** server can't find api.sandbox.push.apple.com: NXDOMAIN
Lookup of the production server works:
nslookup api.push.apple.com
Non-authoritative answer:
api.push.apple.com canonical name = api-vs.push-apple.com.akadns.net.
Name: api-vs.push-apple.com.akadns.net
Address: 17.188.180.206
Name: api-vs.push-apple.com.akadns.net
Address: 17.188.180.76
Name: api-vs.push-apple.com.akadns.net
Address: 17.188.180.138
Name: api-vs.push-apple.com.akadns.net
Address: 17.188.182.203
Name: api-vs.push-apple.com.akadns.net
Address: 17.188.180.78
Anyone having the same problem?
User Notifications
RSS for tagPush user-facing notifications to the user's device from a server or generate them locally from your app using User Notifications.
Posts under User Notifications tag
157 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Back story: I'm developing an app that communicates with a personal medical device. We use critical alerts when we have hardware issues that could result in harm to the patient. The audio file is a 30 second file to make sure the patient is aware. If the app is open when they occur, we pop up a modal message in the app. When the user dismisses the notice, we call UNNotificationCenter::removeDeliveredNotifications(withIdentifiers:) to remove the critical alert and also to stop the audio file that is playing.
This normally works fine. However we discovered that if the patient leaves critical alert enabled but disables notifications for our app, that we can still post the critical alert and it goes off. However when the user dismisses the message, the removeDeliveredNotifications call does not work. I did some debugging and if call getDeliveredNotifications with this permission combination, it return 0 (normally it would return 1).
Does anyone know of another way to remove the critical alert in this situation? (or should I be submitting this as a bug?)
I have been trying to implement APNS Push Notifications into the iOS App I'm currently developing, and I'm having issues with notifications sent via my custom server not being delivered. I have built and ran the App on my device (iPhone running iOS 17.6.1), requested permission for notifications from UNUserNotificationCenter, and saved the device token for testing purposes.
As a sanity check for the device token and the App entitlements, I used the CloudKit tool for testing Push Notifications. The notifications I send aimed at the "DEVELOPMENT" Environment work properly and arrive on the device.
To configure my custom server, I created the Sandbox Apple Push Notifications certificate in my Developer portal, installed it on my Mac, exported the certificate and key together into a .p12 file, and created the PEM file using this command:
openssl pkcs12 -in Certificates.p12 -out sandbox.pem -nodes -clcerts
When my server attempts to send a notification, it appears to connect to the server and send the payload, but the notification never arrives on the device. I don't get any errors when my server writes the notification's binary payload to the connection.
For clarity, here is the code from my server that sends the "aps" payload to APNS (written in PHP):
public function sendPushNotification($deviceToken, $title, $message)
{
$jsonPayload = $this->composePayload($title, $message);
$msg = $this->buildBinaryNotification($jsonPayload, $deviceToken);
$this->connectToApns();
$result = fwrite($this->mApnsConnectionHandle, $msg, strlen($msg));
if (!$result)
{
$this->writeToLog("Message not delivered?!");
} else {
$this->writeToLog("Message successfully delivered!");
}
$this->disconnectFromApns();
}
And this is the code for constructing the JSON payload, and for converting that JSON into a binary string:
private function composePayload($title, $message)
{
// Create the payload body
$body['aps'] = array(
'alert' => array(
'title'=>$title,
'body'=>$message
)
);
// Encode the payload as JSON
$payload = json_encode($body);
return $payload;
}
private function buildBinaryNotification($payload, $deviceToken)
{
if (strlen($payload) > 0 && strlen($deviceToken) > 0)
{
$msg = chr(0) . pack('n', strlen($deviceToken)) . pack('H*', $deviceToken) . chr(0) . pack('n', strlen($payload)) . $payload;
}
return $msg;
}
Any suggestions or advice would be appreciated.
Hello,
I'm doing some test and I dowload the sample from here https://developer.apple.com/documentation/networkextension/local_push_connectivity/receiving_voice_and_text_communications_on_a_local_network
Everything works correctly and the phones are able to exchange messages without problems and the server sends pushes to the devices.
Now I would like to modify the server so that, when it sends the push to the mobile device, it can change the sound or add other information as is possible when using APN.
Now I would like to modify the server so that, when it sends the push to the mobile device, it can change the sound or add other information as is possible when using APN.
Is there any way to send a payload like for APN?
Thank's
Omar
An incident occurred in which the same device token was sent from different IDFVs.
To investigate the cause, please let me know the informations below.
・What are the conditions under which the IDFV changes?
・When an IDFV changes due to uninstallation, etc., does the device token always change?
・Is there a chance that a device token that has been used in the past in another terminal will be used in another IDFV terminal?
Please find below a complete app example.
It has a button, when you press it, a local notification is created. However, the UnNotificationCenter.delegate is called twice, and I can't understand why.
I am trying to move my project from Objective-C to Swift, and my similar code there doesn't get called twice, so I'm confused.
Can anybody shine a light on this? Pointers appreciated.
App:
@main
struct NotifTestApp: App {
init() {
UNUserNotificationCenter.current().delegate = NotificationReceiveHandler.shared
configureUserNotifications()
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
private func configureUserNotifications() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
if granted {
print("Notification permission granted.")
} else if let error = error {
print("Error requesting notification permissions: \(error)")
}
}
}
}
class NotificationReceiveHandler: NSObject, UNUserNotificationCenterDelegate {
static let shared = NotificationReceiveHandler()
//>> THIS IS CALLED TWICE WHEN I PRESS THE BUTTON
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
NSLog(">>> Will present notification!")
completionHandler([.sound])
}
}
///THE UI
struct ContentView: View {
var body: some View {
VStack {
Text("👾")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Notification test!")
Text("When i press the button, will present is called twice!!").font(.footnote)
.padding(10)
Button("Create Notification") {
createNotification(
message: "This is a test notification",
header: "Test Notification",
category: "TEST_CATEGORY",
playSound: true,
dictionary: nil,
imageName: nil)
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
.padding()
}
}
#Preview {
ContentView()
}
private func createNotification(message: String, header: String, category: String, playSound: Bool = true, dictionary: NSDictionary? = nil, imageName: String? = nil) {
let content = UNMutableNotificationContent()
content.title = header
content.body = message
content.categoryIdentifier = category
content.badge = NSNumber(value: 0)
if let imageName = imageName, let imageURL = Bundle.main.url(forResource: imageName, withExtension: "png") {
do {
let attachment = try UNNotificationAttachment(identifier: "image", url: imageURL, options: nil)
content.attachments = [attachment]
} catch {
print("Error creating notification attachment: \(error)")
}
}
content.sound = playSound ? UNNotificationSound(named: UNNotificationSoundName("event.aiff")) : nil
if let infoDict = dictionary {
content.userInfo = infoDict as! [AnyHashable: Any]
}
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
Currently if the app is hidden and locked behind face id even though the notifications are not displayed but the Notification Service Extension still wakes up for the notification.
Is it the expected behaviour ? Or should we expect the NSE would not be used as well when the app is hidden.
Is there a way to export all push notification console information via API or webhook?
in Push Notifications Platform :
when i test the device remove our app , the status result is “- discarded as device was offline”
when i test close the notification auth in our app, the status result is “- stored for device power considerations"
but i saw the flow in doc , I didn't directly saw that these two states are like this https://developer.apple.com/documentation/usernotifications/viewing-the-status-of-push-notifications-using-metrics-and-apns
how can i know the directly status in this two cases ?
About 2 or 3 months ago, when my app receive a Silent Push notification([aps][content-available] = 1), only func "application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler" had triggered.
But now, when my app receive Silent push, my app triggered 3 func :"didFinishLaunchingWithOptions"; "application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo" and "application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler".
Does Apple update this logic? Are there any solution to push silent that just triggered only one func like before?
I am developing a web application with PWA and Vue.js (javascript).
I would like to add a Web Push notification function, so I referred to the following site
to execute notification permission and received the response result "granted".
https://developer.mozilla.org/ja/docs/Web/API/Notification/requestPermission_static
I have tried both requestPermission(); and requestPermission(callback).
However, in this state, an error occurred when subscribing to pushManager, and push notification registration could not be executed.
As a workaround, I found that by changing the notification permission setting from the OS Settings > Notification screen to Off and On,
subscribing to pushManager was successful.
Is there anything else I need to implement other than calling requestPermission(); or requestPermission(callback) to make it executable without following the workaround steps?
In addition, this phenomenon was not occurring around the beginning of June 2024, and it was confirmed that the problem occurred as of August 5th.
The confirmed OS and models are as follows.
iOS 17.4 Mobile Safari iPad
iOS 17.3 Mobile Safari
iOS 15.8 Mobile Safari
iOS 17.3 Mobile Safari iPad
iOS 15.8 Mobile Safari iPad
iOS 17.4 Mobile Safari
iOS 16.7 Mobile Safari
Not sure if this is new (undocumented) behavior or a bug in iOS 18, but I'm seeing the UserNotifications willPresent method being triggered twice in a row for a single push notification.
I've filed a feedback assistant ticket on this, but I'm curious if anyone else has encountered this with the new betas?
I am trying to start a live activity via push token with the below headers and payload. I am using the 'fetch-http2' npm module to execute the APNS request in a deno/typescript environment, and am authenticating via token/p8. The device receives the alert portion of the payload, but the live activity does not appear on the device. I get a 200 OK response from APNS with the unique ID, and dashboard shows notification was successfully sent to the device.
The odd thing, when backgrounding the app dismisses to the Dynamic Island with the animation as if there were a live activity happening, but there is not. When I check Activity<MyAttributes>.activities on app launch, it's empty. I don't see any errors in Xcode when I have the app running/foregrounded when sending the request. Quitting the app restores normal behavior.
TL;DR:
I have regular APNS alert push notification requests working without issue from the same environment. However when attempting to start a live activity via APNS, the alert is received but the live activity does not appear, despite the app/system seemingly thinking there is one. What could I be missing, or what else could I try?
I have checked that:
My generated JWT and device token are valid according to CloudKit dashboard (again, standard push alerts are working as expected)
I can successfully start a live activity locally/from foreground via Activity.request
I have added Supports Live Activities and Supports Live Activities Frequent Updates to my app's info.plist, and also have the required capabilities enabled (remote push, background processing, background fetch)
I am using the current device push-to-start token (obtained from device via Activity.pushToStartTokenUpdates) for the device token in the APNS request (NOT the update token)
My ActivityAttributes and ActivityAttributes.ContentState values and types are correct
"headers": {
"authorization": "bearer {jwt}",
"apns-push-type": "liveactivity",
"apns-topic": "{bundleId}.push-type.liveactivity"
}
"aps": {
"attributes-type": "LiveActivityAttributes",
"attributes": {
"title": "Test Event"
},
"content-state": {
"status": 1
},
"event": "start",
"alert": {
"title": "Alert Title",
"body": "Live Activity has started."
},
"sound": "default",
"timestamp": Math.round(Date.now() / 1000)
}
Hello,
We are developing a parental control app consisting of two parts: a parent app to manage settings and a child app to enforce these settings using iOS's Screen Time API, CoreData, and other components. We've attempted to use silent notifications with Firebase Cloud Messaging (FCM) to communicate updates from the parent app to the child app. Our current implementation involves background modes for remote messages and background tasks.
However, we're facing a challenge: while normal FCM push notifications with a 'message' key work as expected, silent notifications (with only a 'data' key) do not trigger the desired behavior in the child app, even though FCM returns a success response.
We're looking for assistance with two main issues:
Alternative Approaches: Is there a better way to notify the child app of changes? We're considering a system where the child app periodically checks for updates via API and then updates CoreData and managed settings. Any recommendations for this architecture or a more reliable notification system would be greatly appreciated.
Debugging Silent Notifications: If our current approach using silent notifications is feasible, could someone help us debug why these notifications are not working as expected? We've been stuck on this for a week, and any help would be a lifesaver.
Here's the relevant part of our AppDelegate code:
import UIKit
import FirebaseCore
import FirebaseMessaging
import BackgroundTasks
@objc class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
let gcmMessageIDKey = "gcm.message_id"
let backgroundTaskIdentifier = "com.your-company.your-app.silentnotification"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
// Register for remote notifications
UNUserNotificationCenter.current().delegate = self
application.registerForRemoteNotifications()
// Register background task
BGTaskScheduler.shared.register(forTaskWithIdentifier: backgroundTaskIdentifier, using: nil) { task in
self.handleBackgroundTask(task: task as! BGProcessingTask)
}
return true
}
// Handle incoming remote notifications
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let aps = userInfo["aps"] as? [String: Any],
let contentAvailable = aps["content-available"] as? Int, contentAvailable == 1 {
// This is a silent notification
handleSilentNotification(userInfo: userInfo, completionHandler: completionHandler)
} else {
// This is a regular notification
Messaging.messaging().appDidReceiveMessage(userInfo)
completionHandler(.newData)
}
}
// Handle silent notification
func handleSilentNotification(userInfo: [AnyHashable: Any], completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let request = BGProcessingTaskRequest(identifier: backgroundTaskIdentifier)
request.requiresNetworkConnectivity = true
do {
try BGTaskScheduler.shared.submit(request)
performAPICall { result in
switch result {
case .success(_):
completionHandler(.newData)
case .failure(_):
completionHandler(.failed)
}
}
} catch {
completionHandler(.failed)
}
}
// Handle background task
func handleBackgroundTask(task: BGProcessingTask) {
task.expirationHandler = {
task.setTaskCompleted(success: false)
}
performAPICall { result in
task.setTaskCompleted(success: result != nil)
}
}
// Perform API call (placeholder implementation)
func performAPICall(completion: @escaping (Data?) -> Void) {
// Your API call implementation here
// For testing, you can use a simple delay:
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
completion(Data())
}
}
}
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("FCM token: \(fcmToken ?? "nil")")
// TODO: Send this token to your server
}
}
Additionally, here is how we're sending notifications from the server side using Node.js:
// Import the required Firebase Admin SDK (assumed to be initialized elsewhere)
// const { getMessaging } = require('firebase-admin/messaging');
/**
* Sends a background push notification to an iOS device
* @returns {Promise<string>} The message ID if successful
* @throws Will throw an error if the sending process fails
*/
async function sendBackgroundPushNotification() {
// Construct the message object for a background push notification
const message = {
apns: {
headers: {
// Set the priority of the push notification
"apns-priority": "5",
priority: "5",
// Indicate that this is a background refresh notification
"content-available": "1",
content_available: "1",
// Specify the push type as background
"apns-push-type": "background",
// Set the topic to your app's bundle identifier
"apns-topic": "com.your-company.your-app", // Replace with your actual bundle identifier
},
payload: {
aps: {
// This tells iOS to wake up your app in the background
"content-available": 1,
},
},
},
// Custom data payload to be sent with the notification
// Modify this object to include the data you want to send
data: {
// Add your custom key-value pairs here
},
// Uncomment the following block if you want to include a visible notification
// notification: {
// title: "Notification Title",
// body: "Notification Body",
// },
token
token: "DEVICE_FCM_TOKEN_PLACEHOLDER",
};
try {
// Attempt to send the message using Firebase Cloud Messaging
const response = await getMessaging().send(message);
console.log("Successfully sent background data to iOS:", response);
return response;
} catch (error) {
console.error("Error sending background data to iOS:", error);
throw error;
}
}
// Example usage:
// sendBackgroundPushNotification()
// .then((response) => console.log("Message sent successfully:", response))
// .catch((error) => console.error("Failed to send message:", error));
We would really appreciate any insights or guidance on these issues. Thank you!
I am attempting to send a push notification via APNS from a supabase edge function (deno/typescript). I receive a 200 OK response from APNS, and using the "apns-unique-id" I am able to look up the notification in the dashboard which shows the notification was successfully sent to the device. However the app/device does not receive the push.
Using the dashboard, I can successfully send a test push to the device,
and I also have FCM already implemented and working, so I assume the iOS/client-side setup is not the problem. I also verified that my generated JWT and device token are valid via the dashboard, plus I'm getting 200 back with the request, so I also assume that auth is not an issue either. Yet even with a simple alert payload such as below, nothing comes through.
What else could be causing this issue? Perhaps I'm missing a step? The details of the request I'm making are below:
url = "https://api.sandbox.push.apple.com:443/3/device/{deviceToken}"
headers = {
"authorization": "Bearer {jwt}",
"apns-push-type": "alert",
"apns-topic": bundleId,
"apns-priority": 10
}
body = {
"aps": {
"alert": {
"title": "Test Notification",
"body": "This is a test notification.",
"sound": "default"
}
}
}
According to the documentation (https://developer.apple.com/documentation/usernotificationsui/unnotificationcontentextension), a Notification Content Extension should consist of a UIViewController that adopts the UNNotificationContentExtension protocol.
The only problem is that UNNotificationContentExtension's methods are not @MainActor isolated, but UIViewController is, which produces this error when you try to build your code with Complete concurrency checking turned on:
Main actor-isolated instance method 'didReceive' cannot be used to satisfy nonisolated protocol requirement
If you add nonisolated, you are then left with another problem in that UNNotification is not Sendable.
What is the recommended solution to this problem?
Experiencing 403s (InvalidProviderToken) [https://api.push.apple.com/3/device/] due to invalid or unverifiable provider tokens. We have noticed that after retrying the request inline, the notification is delivered successfully without any changes to the request even with same authorization token.
Someone please guide or suggest why it is happening as the JWT token which is generated is correct because we are caching the jwt token and using the same token to send out the subsequent request which is kind of successfull.
Sending the notification for multiple team Ids under the same application.
Tried all these steps
Force restart
DIsabled focus mode
Notifications are enabled in both device and in app settings
Disabled summary notifications.
Tried sending notification from pusher tool, that also is not showing up in the center, for the device effected but on another device it is working fine for the same application(same version too)
What could be the reason and a possible solution?
Tried all these steps
Force restart
DIsabled focus mode
Notifications are enabled in both device and in app settings
Disabled summary notifications.
Tried sending notification from pusher tool, that also is not showing up in the center.
What could be the reason and a possible solution?
When a user receives a provisional notification and they click the "Keep" button and choose deliver immediately, there is no OS setting changes. The notifications are stuck in "delivered quietly" unless the user happens to change that in their Settings.