User Notifications

RSS for tag

Push 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

154 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Why is willPresentNotification called twice here?
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) }
3
0
122
3d
There are some difference between Push Notifications Platform 's statue result and doc
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 ?
0
0
110
6d
Silent Push Notification in background also triggered didFinishLaunchingWithOptions
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?
1
0
133
1w
push notification on safari not work.
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
0
0
279
2w
Live Activity not showing when started via push notification, but alert is received and app dismisses to dynamic island
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) }
0
0
209
2w
Issues with Silent Notifications in Parental Control App Using FCM and Background Tasks
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]?) -&gt; 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) -&gt; 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) -&gt; 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?) -&gt; 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&lt;string&gt;} 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) =&gt; console.log("Message sent successfully:", response)) // .catch((error) =&gt; console.error("Failed to send message:", error)); We would really appreciate any insights or guidance on these issues. Thank you!
5
0
234
2w
APNS push is not received by device when sent via backend despite 200 OK response received
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" } } }
1
0
219
3w
Notification Content Extension and Swift Complete Concurrency
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?
2
1
238
3w
Receiving 403 (InvalidProviderToken) from APNs Send Notification service
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.
1
0
266
Jul ’24
Not getting notifications from some apps on iOS 17.5.1
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?
2
0
251
Jul ’24
Custom Push Notification for Apple Wallet Pass not Showing up on iPhone
I've implemented pass generation successfully and it's updated through Apple's silent notification, which updates the passes to their latest versions. I want to send some marketing push notifications to the Apple Wallet App as shown in my post at stackoverflow. Here is the Silent notification implementation, which is working perfectly fine. const options: apn.ProviderOptions = { token: { key: fs.readFileSync("./certs/APNs_AuthKey_7YYF346FU5.p8"), keyId: "******", teamId: "******", }, pfx: fs.readFileSync("./certs/private_key.pem"), cert: fs.readFileSync("./certs/certificate.pem"), production: true, rejectUnauthorized: true, }; const apnProvider = new apn.Provider(options); async function sendSilentPushNotification( deviceTokens: string[], serialNumber: string ) { try { const notification = new apn.Notification(); notification.topic = "pass.com.digital.passmaker"; notification.payload = { aps: { "content-available": 1, }, serialNumber, }; notification.priority = 5; return await apnProvider.send(notification, deviceTokens); } catch (error) { logger.error("Apple Notification error: " + error); return error; } } Here is the marketing notification I am trying to send, it is working with success, but I don't see any notification on mobile phone. please help me to fix it. async function sendCustomPushNotification( deviceTokens: string[], serialNumber: string, title: string, body: string, category?: string, badge?: number ) { try { const notification = new apn.Notification(); notification.topic = "pass.com.digital.passmaker"; // Set the title and body of the notification notification.alert = { title: title, subtitle: "Pass Update", body: body, }; // Set the sound to play when the notification is received notification.sound = "default"; // Set the badge number on the app icon (optional) if (badge !== undefined) { notification.badge = badge; } notification.contentAvailable = true; notification.mutableContent = true; notification.aps.category = category; notification.aps.alert = { title: title, body: body, }; notification.aps.badge = badge; notification.aps["content-available"] = 1; notification.aps["launch-image"] = "https://banner2.cleanpng.com/20180423/gkw/.......jpg"; // You can still include the serialNumber in the custom payload notification.payload = { serialNumber: serialNumber, aps: { "content-available": 1, "mutable-content": 1, "interruption-level": "time-sensitive", }, }; // Set to high priority notification.priority = 10; return await apnProvider.send(notification, deviceTokens); } catch (error) { logger.error("Apple Notification error: " + error); return error; } } I literally receive a success response from api returning the device pushToken with no errors. However, no notification show on my iPhone
0
0
192
Jul ’24
Custom Notification Sounds Not Updating Without System Restart on macOS
I'm a macOS app developer, and I'm facing an issue with custom notification sounds in my app. After upgrading the app to include new custom notification sounds, the changes do not reflect until the system is restarted. The sounds do not update immediately after the app upgrade. Is there a way to refresh or reload the custom notification sounds without needing a full system restart? Any guidance or best practices to handle this would be greatly appreciated. Thank you!
0
0
201
Jul ’24
Custom Notification Sounds Not Updating Without System Restart on macOS
Hello, I'm a macOS app developer, and I'm facing an issue with custom notification sounds in my app. After upgrading the app to include new custom notification sounds, the changes do not reflect until the system is restarted. The sounds do not update immediately after the app upgrade. Is there a way to refresh or reload the custom notification sounds without needing a full system restart? Any guidance or best practices to handle this would be greatly appreciated. Thank you!
0
0
187
Jul ’24
Local push for wake up an app
Hello, We a company that deals with alarm systems in hospitals and we would need to manage, for one of our apps, that the application, even if in the background, can be reactivated and brought to the foreground showing the type of alarm received. We learned of a Dutch company who, they say, thanks to a special agreement with Apple, managed to achieve this using Local Push. We have already done something similar with Android through Foreground services and we would like to do something similar for iOS too but at the moment we have not succeeded because it seems the OS of mobile devices does not allow it. Apart from the normal documentation on local push I can't find much other information about it. Is there anyone at apple who could help me? Thanks
1
0
257
Jul ’24
Set up-to-date badge count when using UNNotificationRequest with trigger
hi, I am trying to schedule a UNNotificationRequest at a certain date using UNCalendarNotificationTrigger, and I also want to update the badge count accordingly. However the badge property in UNNotificationContent can only be set when adding UNNotificationRequest, not when the trigger is fired or notification is actually delivered. How can I set up-to-date badge count if notification is scheduled in the future? For example, if I scheduled notification A to 3 hours later with badge count 1, and in between I got notification B, badge count should be 2 when A is delivered but it will be 1. I am aware of didPresent delegate which can be used when app is in foreground when notification is delivered, but is there any delegate that is called when UNNotificationRequest is delivered and app is backgrounded or we are using NSE? Thanks.
1
0
235
Jul ’24