Notifications

RSS for tag

Learn about the technical aspects of notification delivery on device, including notification types, priorities, and notification center management.

Notifications Documentation

Posts under Notifications subtopic

Post

Replies

Boosts

Views

Activity

Questions about VoIP Push compliance rules and CallKit handling
Hello everyone, I’m an iOS developer working on a real-time communication app that supports VoIP calls using CallKit. The app has been in production for more than 5 years. Over the years, some users have occasionally reported that they do not receive incoming call pushes. We have tried multiple optimizations on both the client and server side, but the improvement has been limited. From Apple documentation and discussions online, I understand that iOS may restrict VoIP pushes if the system detects violations of VoIP push usage rules (for example, not presenting a CallKit call after receiving a VoIP push). However, the exact rules and thresholds for these violations are not clearly documented, so I’d like to ask a few questions to better understand the expected behavior. Below is a simplified description of our current call flow. Call Flow Caller When the user initiates a call: We do not use CallKit The call is handled entirely using a custom in-app call UI Callee When the user receives a call: Device locked or app in background A VoIP push wakes the app The app presents the CallKit incoming call UI App in foreground The server still sends a VoIP push The app first reports the call to CallKit After a very short delay, the app programmatically ends the CallKit call Then a custom in-app call UI is presented via the app's long connection The reason we always send a VoIP push (even when the app is in the foreground) is that we want to maximize call delivery reliability.
7
0
1.1k
1d
AlarmKit: supported audio handoff for staggered overlapping alarms?
We can reproduce an AlarmKit audio failure on iPhone 16 Plus / iOS 26.6.2 (23G90) with a reduced SwiftUI app using fixed-date alarms and .default sound: Schedule three alarms at +60, +180 and +300 seconds. Leave the app visible and the phone untouched. The first alarm sounds. When the +180 alarm triggers, the +60 alarm is silenced (but still active). When the +300 alarm triggers, all three alarms will remain silent, however alarmUpdates reports one, then two, then three .alerting IDs. A single alarm in the same binary sounded continuously for at least 3 minutes 30 seconds. The reduced app has no custom intents, widget, countdown/snooze, audio session, background modes, notifications, packages or automatic cancellation. This exact reduced binary has one recorded comparison; earlier harness configurations also exhibited the failure. Sound was observed by the tester, separately from API logs. When +180 mutes +60, stopping the +60 alarm causes the +180 alarm banner to present itself and become audible. +300 triggering will then mute the +180 alarm. Likewise, stopping the +180 alarm will cause the +300 alarm to present itself and become audible. If you allow +60, +180, and +300 alarms to trigger without touching the screen, all three alarms will be silent at this point. Pressing "Stop" on +60 will cause the +180 banner to present itself and become audible, "Stop" on +180 will cause +300 alarm to then present and become audible. It is for these reasons that I believe there is a bug that occurs when an additional queued alarm transitions from "scheduled" to "active" status that causes the present active alarm to silence. In a foreground harness run, programmatically cancelling the +60 alarm's alerting ID caused the +180 alarm to sound. However that requires app execution and does not establish a background solution. The snooze/coincident-time report looks like it could be related. The FAQ's same-time scheduling answer also seems to describe a different case. What is the supported audio behavior when a later alarm becomes due while an earlier one remains alerting? Is there a scheduling or handoff pattern that preserves audible delivery without requiring the app to execute at each arrival? If overlap is unsupported, which documented constraints should applications follow? If anyone else has experienced this issue and has found a technical workaround I would appreciate hearing about it. For any Apple staff reading this, there is more information on this issue in Feedback Assistant ID FB24757864.
0
0
74
3d
Optimizing the Audio Ducking System: Solving the Lost Revenue Problem for the Apple Ecosystem and Third-Party Developers
Dear Apple Team, I am writing to propose an update to the audio management algorithms in iOS, specifically the automatic Audio Ducking feature during incoming notifications. The inability to disable this function not only creates daily discomfort for users but also directly harms the marketing effectiveness of both third-party services and the Apple ecosystem itself. Currently, the iOS architecture forces the user to choose between two scenarios, both of which are destructive to business: Damage to apps' marketing systems (if device sound is on) Music is a source of emotional pleasure and focus. When the system forcibly ducks the track's volume for a notification sound, users perceive it as an aggressive and annoying intrusion. Instead of engaging with the offer or message, the user feels negativity toward the sending app. The marketing tool (push notification) backfires: to protect their comfort, the user either dismisses the notification without looking or permanently revokes the app's notification permissions, destroying the communication channel and lowering engagement rates. 2. Damage to the reliability and reputation of the Apple ecosystem (if sound is off) Trying to avoid the annoyance described in the first point, the user resorts to the only available workaround — switching the iPhone to silent mode using the physical switch. However, after listening to music, this switch is often left in the silent position. Result: missed important calls, derailed work arrangements, or ignored emergency messages. In this scenario, Apple's reputation suffers. Because of the company's reluctance to add one simple audio focus setting, the device stops performing its core function as a reliable communication tool. The system literally forces the user to "cut" themselves off from the world for the sake of comfortable music listening, leading to negative real-world consequences. Proposed Solution: Introduce a toggle in the "Sounds & Haptics" (or "Accessibility") settings: "Do not duck media for notifications." Alternatively, allow notification sounds to play over the music without altering the main audio stream's volume. Apple has always been known for putting human comfort first. Adding this feature will solve a serious behavioral issue. It will preserve audience loyalty to third-party push campaigns and ensure that iPhone owners stop missing important life events due to the forced use of silent mode. Thank you for your time and attention to user experience. I hope this improvement finds its way into upcoming iOS updates. Sincerely, An Apple Ecosystem User
0
0
104
4d
LiveCommunicationKit: In‑call banner missing in foreground, only appears after app goes background (iPhone14 Pro)
Environment: Device: iPhone 14 Pro iOS version: 26 SDK: LiveCommunicationKit App status: Foreground / Active state Problem reproduction: Intermittent, happens on some devices, not 100% reproducible on all test devices. Expected behavior: Incoming call banner should present when app is active (foreground). Actual behavior: No system incoming‑call banner while app is foreground. Banner appears only after pressing home‑button / switching app to background. Additional notes: Our app uses LiveCommunicationKit because VoIP PushKit is not permitted for China mainland App Store distribution. Call reporting completes without error; no error returned from LiveCommunicationKit API. private func _lckReportIncomingCall(call: Call?, uuid: UUID, handle: String, hasVideo: Bool, displayName: String) { guard let manager = conversationManager else { Log.error("[ProviderDelegate-LCK] ConversationManager is nil, falling back") _fallbackReportIncomingCall(call: call, uuid: uuid, handle: handle, hasVideo: hasVideo, displayName: displayName) return } let callInfo = callInfos[uuid] let callId = callInfo?.callId ?? "" let remoteHandle = Handle(type: .generic, value: handle, displayName: displayName) let update = Conversation.Update(localMember: nil, members: [remoteHandle], activeRemoteMembers: [remoteHandle]) // 冷启动时 iOS PKPushRegistry 要求在 2 秒内上报来电,否则杀进程。 // Task { @MainActor } 是异步的,调试时主线程 RunLoop 来不及调度就超时了。 // 这里用 DispatchSemaphore 在后台线程同步等待 LCK 上报完成。 let semaphore = DispatchSemaphore(value: 0) var lckError: Error? DispatchQueue.main.async { Task { @MainActor in do { try await manager.reportNewIncomingConversation(uuid: uuid, update: update) Log.info("[ProviderDelegate-LCK] Reported incoming conversation: callId=\(callId), uuid=\(uuid)") if TelecomManager.shared.endCallkit { CoreContext.shared.doOnCoreQueue(synchronous: true) { core in let linphoneCall = core.getCallByCallid(callId: callId) if linphoneCall?.state == .PushIncomingReceived { try? linphoneCall?.terminate() } } } } catch { Log.error("[ProviderDelegate-LCK] Failed to report incoming conversation: \(error)") lckError = error } semaphore.signal() } } let waitResult = semaphore.wait(timeout: .now() + 5) if waitResult == .timedOut { Log.error("[ProviderDelegate-LCK] Timed out waiting for LCK report, falling back") _fallbackReportIncomingCall(call: call, uuid: uuid, handle: handle, hasVideo: hasVideo, displayName: displayName) } else if let error = lckError { Log.error("[ProviderDelegate-LCK] LCK report failed: \(error), declining SIP call") // 来电被拒(勿扰/黑名单等),decline 掉 SIP 侧 CoreContext.shared.doOnCoreQueue(synchronous: true) { _ in try? call?.decline(reason: .Busy) } } }
1
0
270
6d
AlarmKit on iOS 27 beta: alarmUpdates delivery deferred until app runs, stale re-presentation, audio without UI under Focus (FB23754550)
Feedback: FB23754550 (filed July 14, 2026, still Open, no response) App: AlarmWizard, com.UBSAnalyticsLLC.AlarmWizard, shipping on the App Store Device: iPhone 17 Pro Max Current OS: iOS 27.0 (24A5408d). First seen on iOS 27.0 Seed 3 (24A5380h). Still reproducing on 24A5408d as of September 2, 2026. Baseline: same app binary on iOS 26 release, same hardware, behaved correctly. No iOS 26 production user has reported any of the behaviors below. Alarm under test: Alarm.Schedule.Relative, Mon through Fri, 07:05 America/New_York. The app writes a timestamped file log of every AlarmManager.alarmUpdates emission, every BGTaskScheduler execution, and every scheduling call. All times below come from that log unless noted. ISSUE 1: alarmUpdates .alerting transition is not delivered while the app is suspended. It queues until the app next gets runtime. On iOS 26 the observer received .alerting at the scheduled minute with the app suspended (logged May 1 and May 6 at 06:35, the exact fire time). On iOS 27 the transition arrives only when the app next runs, almost always at unlock. Delivery lag for the 07:05 occurrence: Jun 15: observed 08:50 (+1h 45m, unlock) Jun 22: observed 09:15 (+2h 10m, unlock) Jun 23: observed Jun 24 02:56 (+19h 51m, BGProcessingTask woke the app) Jun 26: observed 17:22 (+10h 17m, unlock) Jun 30: observed 12:12 (+5h 07m, unlock) Jul 6: observed 09:08 (+2h 04m, unlock) Jul 7: observed 09:00 (+1h 55m, app opened) Jul 9: observed 07:06 (+81s, user unlocked right after dismissing) The lag always equals time-until-the-app-next-ran, across three app builds. The Jun 23 case crossed midnight, so the event landed on the next calendar day. Expected: .alerting delivered at or near fire time as on iOS 26, or documentation stating delivery is deferred to app runtime. Actual: delivery deferred up to about 20 hours. ISSUE 2: the system alarm UI re-presents an occurrence hours after its scheduled time. Jun 15: the 07:05 occurrence presented (lock screen alert with Snooze and slide-to-stop, plus sound) at 08:49. Lock screen screenshot attached to the FB. Jun 30: the 07:05 occurrence presented at 14:25. Paired screenshots from the same minute show the system alert ("Work Week", 2:25) next to the app's full alarm list (a disabled 5:45 AM and the 7:05 AM Work Week alarm, nothing near 14:25). The observer logged alerting to scheduled at 14:25:48. Expected: an alarm presents once, at its scheduled time. Actual: stale re-presentation up to 7+ hours late, and presentation of a disabled alarm. ISSUE 3: with a Focus (Do Not Disturb) active, the alarm played audio with no lock screen presentation. Jul 7, DND on overnight. At 07:05 the alarm sound played but no lock screen alarm UI appeared, only the indicator in the Dynamic Island. There was no way to stop it from the lock screen. Opening the app showed the alarm still in .alerting (our in-app firing UI appeared and the user stopped it there at 09:00). Expected: full presentation (UI and audio) breaking through Focus, per AlarmKit's stated purpose. Actual: audio only, no lock screen UI. ISSUE 4 (corroborating, no timestamped log): an AlarmKit countdown timer (AlarmManager.AlarmConfiguration.timer) presented its alert with no audio. The inverse of Issue 3. Presentation and audio appear to fire independently on iOS 27. HOW WE ISOLATED THE OS The identical binary ran on iOS 26 through early June with on-time delivery and no phantom presentations. The device was upgraded to the iOS 27 beta mid-June with no app change and the first stale presentation occurred Jun 15. Several internal builds since, including hardening for late delivery, changed nothing about the delivery lag. Every anomaly was checked against the log. Several suspected framework bugs were traced to our own code and fixed and are not reported here. In every case above, the log shows the app was suspended and received no callback at the relevant time, so the presentation, audio, and delivery behavior originated in the system. ATTACHED TO FB23754550: three production log exports (Jun 22 through Jul 9), the Jun 15 and Jun 30 lock screen screenshots, and a sysdiagnose captured Jul 14 (sysdiagnose_2026.07.14_19-19-40-0400_iPhone-OS_iPhone_24A5380h). I can capture a fresh sysdiagnose on 24A5408d immediately after the next occurrence if a targeted profile would help. Questions for Apple: Is deferred alarmUpdates delivery while suspended intended on iOS 27? If so, where is it documented, and what is the supported way to react to an alarm firing while the app is not running? Is there any known issue covering re-presentation of past occurrences? Is the Focus behavior in Issue 3 a known regression? With the iOS 27 RC expected this month, I would appreciate confirmation that this is on someone's radar.
2
0
198
1w
registerForRemoteNotifications gives neither a token nor an error for one bundle ID in production; development-signed build registers instantly
On a single device, a production-entitlement build of our app calls -[UIApplication registerForRemoteNotifications] and neither delegate callback is ever invoked. Not application:didRegisterForRemoteNotificationsWithDeviceToken:, and not application:didFailToRegisterForRemoteNotificationsWithError:. We wait 10 seconds and get nothing, on every launch, over more than 24 hours. UNAuthorizationStatus is .authorized, verified programmatically at the moment of the call rather than just in Settings, and the installed binary carries aps-environment = production, read off the device. The identical source signed with aps-environment = development receives a token in under one second on that same handset. We have isolated it to one cell of a four-way matrix. Production entitlement on this device: no token, no error, reproducing on both the App Store and TestFlight builds. Development entitlement on this device: token in under one second. Production entitlement on other devices: works, and other users register daily. Production APNs for other apps on this device: works, other App Store apps receive push normally. Already ruled out: notification authorization; the entitlement; delegate wiring (UIApplicationDelegateAdaptor is attached, and that same delegate receives the token when the app is development-signed); delete and reinstall from both the App Store and TestFlight; Reset Network Settings; reboot; airplane-mode cycle; an alternate network. Device context: iPhone 12 Pro (iPhone13,3) on iOS 26.6.1 (23G83). It is an AppleCare replacement unit, restored from a backup of the previous handset. Our working theory is stale per-app push registration state carried across in that restore, since reinstalling does not clear it, which suggests whatever is stuck does not live in the app container. Filed as FB24525199 with a sysdiagnose captured while the APNs logging profile was installed. Two questions. First, is there any way to force a device to discard and re-provision its per-app APNs registration state, short of erasing and setting up as new? Second, is the absence of both callbacks a known state? Every reference I can find treats didFailToRegisterForRemoteNotificationsWithError as the guaranteed path when registration cannot complete, so silence from both leaves an app with no signal to act on and no way to tell the user what is wrong.
5
0
197
2w
APNs proper behavior when connections are reset without warning
The company I work for sends large amount of traffic to APNs on behalf of our customers, with rates up to 50k/second at peek times. While a vast majority of the messages are successful or return a proper error code that we can parse and honor, roughly 1.5 million times per day our connections are being closed without warning. The networking library we use, https://github.com/hyperium/h2, is exposing these as ErrorKind::ConnectionReset or ErrorKind::BrokenPipe. From our reading of the APNs documentation, it is unclear what the correct response is when this occurs. There is no idempotency key included with our messages, so attempting to resend the message again seems frought with the potential for double sends. However, it some cases it seems clear that at least some of the messages in flight over that connection where never sent out at all. We found this open source project unconditionally retrying messages in this case. https://github.com/rpush/rpush/pull/734 Could someone from the APNs team please lay out the expected behavior a client should have when our connection is unexpected closed in this manner?
0
0
132
2w
Removing an unrelated AccessorySetupKit device invalidates notification forwarding sessions for accessories from another app
We are seeing a cross-app session-isolation issue involving DeviceAccess / AccessorySetupKit and Accessory Notifications. Setup: Garmin Connect owns an authorized Forerunner 745. Our app owns an Amazfit Active 3 Premium and an Amazfit Bip Max. Both Amazfit devices have working NotificationsForwarding DAExtensionSession instances. Reproduction: Keep notification forwarding working for the Amazfit devices, then forget the Garmin Forerunner 745 in iOS Settings > Bluetooth. DeviceAccess correctly removes only the Garmin device and emits DeviceLost for Garmin DeviceID C175AA77-... (com.garmin.connect.mobile). In the same millisecond, usernotificationsd invalidates two unrelated NotificationsForwarding sessions: CID 0x2D07001D, DeviceID 13D01E46-..., BundleID com.huami.watch CID 0x2D07001C, DeviceID D86C37A0-..., BundleID com.huami.watch The second session belongs to Bip Max. About four seconds later, notifications fail with: post() failed: no connection hasExtensionSession: false Bip Max remains Authorized and BTPaired, and its DADevice and notification capability remain present. Only its usernotificationsd-held NotificationsForwarding DAExtensionSession is lost. usernotificationsd also logs AccessoryNotifications.AccessoryError Code=5 while clearing the Garmin accessory record. Should DeviceLost ever invalidate NotificationsForwarding sessions with a different DeviceID and owning app? Is there a supported way to rebuild the missing session without removing and re-authorizing the retained accessory? Timestamp: 2026-08-31 14:08:46.973 local time. Full identifiers, tokens, and logs are omitted; we can provide a sysdiagnose and log archive through Feedback Assistant.
0
0
159
2w
APNs 410 Unregistered Spike and Invalid Token Behavior
Hello Apple Developer Technical Support, We observed an unusual increase in APNs 410 Unregistered responses in our production iOS app between July 10 and July 24, 2026: Before July 10: approximately 1,500–5,000/day July 10–24: approximately 15,000–30,000/day, a 5–10x increase After July 24: the volume stabilized and did not continue to increase We found no relevant changes to our client, server, or APNs configuration during this period, and no corresponding increase in 403 ExpiredProviderToken or 400 BadDeviceToken. We also found that the last app-open dates of the affected tokens were broadly distributed from August 2025 to June 2026, with no clear concentration around a specific inactivity period. We are not using 410 Unregistered as an uninstall signal. Our main concern is understanding why the response volume increased so significantly during this specific period. Could Apple confirm: Whether there were any APNs-side changes, maintenance activities, or changes in token processing behavior between July 10 and July 24 that could explain this increase? For a device token that becomes invalid due to app uninstallation, after how many push attempts would APNs typically return a 410 Unregistered response? Is it expected to return 410 on the first push attempt, or only after multiple push attempts?
0
0
226
2w
Multi-accessory DeviceAccess routing issues: notification sessions invalidated and replies wake the wrong Transport
Title: Multi-accessory DeviceAccess bugs: wrong PeripheralID in Transport wake-up; cross-device NotificationsForwarding session invalidation Topic: App & System Services → Core OS Tags: Core Bluetooth, AccessorySetupKit, Notifications Body: Context: our app uses AccessorySetupKit and a DeviceAccess-based accessory Transport + DataProvider extension pair (one shared extension bundle serves all accessories). Everything works with a single bound accessory, but with two or more ASK accessories on the same app we consistently hit two independent system-level failures. Both fail BEFORE any app callback runs (no DataProvider addNotification, no Transport messageReceived), so this is not app-side parsing or business logic. Tested on iPhone 11 Pro, current iOS 26 release; full logarchives available and can be attached to a Feedback Assistant case. Problem 1 — Transport wake-up requests use the wrong PeripheralID (uplink: watch reply → iPhone) Reproducible timeline from bluetoothd/deviceaccessd logs: Device A's GATT indication reaches bluetoothd; CoreBluetooth routes it to device A's CoreBluetooth session (its Transport PID). ~8 ms later, the DAExtensionRuntimeAssertion that bluetoothd sends to deviceaccessd carries device B's PeripheralID instead of device A's. deviceaccessd then resumes/updates device B's Transport. Device A's Transport stays suspended and never receives the data; the reply is lost. Two outcomes depending on whether the wrongly-used PeripheralID still resolves: Belongs to another still-bound accessory: the assertion "succeeds" and the wrong Transport instance is resumed — no error at all. Belongs to an already-removed accessory: DAErrorDomain 350002 "device not found". So the absence of error 350002 does not mean the mapping is correct. Re-authorizing the affected accessory via ASK does NOT repair the mapping: after re-ASK, notification delivery works again, but once the new Transport suspends, subsequent wake-ups still carry the other accessory's PeripheralID. Problem 2 — NotificationsForwarding DAExtensionSession lifecycle is not isolated per DeviceID (downlink: iPhone notification → watch) Expected: usernotificationsd holds one NotificationsForwarding DAExtensionSession per authorized accessory with notification forwarding enabled, strictly isolated by DeviceID. Observed instead: A session is "activated and stored" and then immediately invalidated by usernotificationsd itself, with no user action (four-accessory setup, three forwarding-capable). Any accessory's DeviceLost invalidates OTHER accessories' sessions. Logs show the event DeviceID differs from the invalidated session's DeviceID. This also happens when the removed accessory does not support notification forwarding at all (so there was no session of its own to clean up). After such mass invalidation, usernotificationsd may rebuild only some sessions or none — even when BLE, Transport, and DataProvider capability fully recover (e.g. after toggling Bluetooth). Notifications then stop at "post() failed: no connection (hasExtensionSession: false)". A new accessory's ASK DeviceFound triggers a rescan that rebuilds missing sessions for the older devices (consistent across our samples, but we don't know whether this is a stable contract). What we ruled out on our side: ASAccessorySession.removeAccessory is called with the correct target; nothing in the app touches other accessories' sessions or permissions. The failures happen inside system daemons before app callbacks; single-accessory flows work fine with identical code. Multiple DataProvider DAExtension records sharing one host PID behaved normally — expected ExtensionKit hosting, not the issue. Questions: Is the PeripheralID substitution in the bluetoothd → deviceaccessd DAExtensionRuntimeAssertion a known issue when one transport extension bundle serves multiple accessories? Any supported workaround? Should usernotificationsd session maintenance be strictly isolated by DeviceID? Is there a supported way to force-rebuild all NotificationsForwarding DAExtensionSessions without unbinding accessories? Is the DeviceFound-triggered full session rescan/rebuild a contract we may rely on? Happy to provide logarchives and detailed timelines via Feedback Assistant. Thanks!
0
0
291
2w
FCM Token Not Receiving Notifications Despite Successful Token Retrieval on iOS
We are facing an issue with push notifications on our iOS production application and would appreciate guidance. Issue Summary Push notifications were working correctly previously but stopped working around two weeks ago. We use Firebase Cloud Messaging (FCM) for push notifications, which delivers notifications to our iOS application through APNs. The issue appears to be related to existing FCM tokens. Existing FCM Token We have an FCM token already stored in our production backend database. When we try to send a notification using this token: Our backend sometimes receives the following response: { "error": { "code": 404, "message": "NotRegistered", "status": "NOT_FOUND", "details": [ { "@type": "type.googleapis.com/google.firebase.fcm.v1.FcmError", "errorCode": "UNREGISTERED" } ] } } In some cases, the API request appears successful, but the notification is still not received on the iPhone. We also copied the exact same existing token and tested it directly using Firebase Console → Send test message. The notification was not received on the device. Newly Generated / Retrieved FCM Token We then generated/retrieved the FCM token again from the same application and tested it directly from Firebase Console. Using the newly retrieved token: The notification was successfully received on the same iPhone. This means the following behaviour is observed: Existing FCM Token ↓ Backend may return 404 UNREGISTERED OR Firebase may accept the send request ↓ Notification not received But after retrieving the token again: FCM Token Retrieved Again ↓ Firebase Console Test ↓ Notification received successfully Client-Side Configuration We have confirmed the following: APNs device token is successfully generated. FCM registration token is successfully generated. Notification permission is granted. The application is connected to the correct Firebase project. FirebaseAppDelegateProxyEnabled is set to NO. Since Firebase method swizzling is disabled, we manually assign the APNs token to Firebase Messaging. Our APNs registration code is: func application( _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data ) { print("*** APNS Device Token: ", deviceToken) Messaging.messaging().apnsToken = deviceToken Messaging.messaging().subscribe(toTopic: "testing_new_events") { error in if let error = error { print("*** Failed to subscribe: \(error.localizedDescription)") } else { print("*** Subscribed to topic successfully") } } } Main Question About the 404 UNREGISTERED Response One part of this behaviour is particularly confusing to us. If Firebase returns: 404 UNREGISTERED NotRegistered for a particular FCM token, we would expect that token to be invalid and that the application should receive or generate a completely new FCM registration token. However, when we retrieve the FCM token again from the application, Firebase may return the same token value again. Our question is: If Firebase considers an FCM token unregistered and returns 404 UNREGISTERED when sending a notification, why can Messaging.messaging().token() or the token callback still return the same token again instead of generating a new token? For example: Token A stored in backend ↓ Backend sends notification ↓ FCM returns 404 UNREGISTERED ↓ App retrieves FCM token again ↓ Firebase returns Token A again We would like to understand whether this is expected behaviour. Specifically: Does UNREGISTERED always mean that the locally cached FCM token should immediately be replaced with a new token? If not, why can the same FCM token still be returned to the application after Firebase returns UNREGISTERED for it? Is there a delay between Firebase invalidating a registration for sending and the client generating a replacement token? Is there a recommended way to force Firebase Messaging to refresh or re-register an FCM token after receiving UNREGISTERED? Could the token be cached locally even though its server-side registration is no longer valid? Additional Questions We would also appreciate guidance on the following: Is it possible for an existing FCM token to become stale or no longer usable for notification delivery without immediately returning an UNREGISTERED error for every send attempt? Can Firebase accept a message for an existing token and return a successful response, while the notification is never delivered to the device? On iOS, could the relationship between an existing FCM token and its APNs token become invalid or stale, while the application still returns the same FCM token? Is there any APNs-side reason why an old FCM token would stop receiving notifications while a newly generated/retrieved token on the same device receives notifications successfully? What is the recommended client-side and backend-side handling after receiving a 404 UNREGISTERED response? Should we immediately remove the token from our database and wait for the application to register a new token? Our main concern is understanding why an FCM token can receive a 404 UNREGISTERED response during sending, but the application can still return the same token when we attempt to retrieve it again. Any guidance on whether this behaviour is expected, particularly regarding the interaction between FCM token registration and APNs on iOS, would be greatly appreciated.
0
0
237
2w
Any options for automated testing of notifications?
My app uses a notification service extension and a notification content extension, both of which are considerably complex and result in a few different dozen combinations of notification with various layouts and content. Regression testing of all the multitude of combinations of notifications is time consuming. Is there any tools available that can utilized to create a test harness? I was thinking something like the test harness sends a series of pushes and each resulting notification gets checked. Is XCUITest capable of verifying the content/layout of notifications? If so how could XCUITest be incorporated with a test harness that is driving things and sending the pushes etc.
0
0
133
3w
Push Notification Icon Not Updated on Some Devices After App Icon Change
Hi, We recently updated our app icon, but the push notification icon has not been updated on some devices. It still shows the old icon on: • iPhone 16 Pro — iOS 26 • iPhone 14 — iOS 26 • iPad Pro 11” (M4) — iOS 18.6.2 • iPhone 16 Plus — iOS 18.5 After restarting these devices, the push notification icon is refreshed and displays the new version correctly. Could you advise how we can ensure the push notification icon updates properly on all affected devices without requiring users to restart? Thank you.
5
3
1.8k
3w
Production APNs rejects a valid production device token with BadEnvironmentKeyInToken (newly released app)
My app was approved and released on the App Store on Aug 19, 2026 (bundle ID br.com.stackads.app, Team ID MSGM29Z362). Push notifications do not work on the production/App Store/TestFlight build. Android via FCM works fine; only iOS production APNs fails. It has been more than 48 hours since release. I captured the raw APNs device token directly from application(_:didRegisterForRemoteNotificationsWithDeviceToken:) in a production (App Store distribution) build (aps-environment = production, verified in the built .ipa entitlements). Sending directly to APNs with a token-based .p8 auth key (Key ID VXXXXXXX, Team ID MSGM29Z362), apns-topic br.com.stackads.app, apns-push-type alert, returns: api.push.apple.com (production): HTTP 403 {"reason":"BadEnvironmentKeyInToken"} api.sandbox.push.apple.com (sandbox): HTTP 400 {"reason":"BadDeviceToken"} The provider (JWT) authentication succeeds (I get a device-token error, not an auth error), so the key is valid. The App ID has the Push Notifications capability enabled. The token is freshly registered (confirmed identical between the didRegister callback and getAPNSToken). Why does the production APNs endpoint reject a valid production device token for this App ID with BadEnvironmentKeyInToken? Is there something pending in the production APNs provisioning for a newly released App ID?
0
0
233
3w
didRegisterForRemoteNotificationsWithDeviceToken never fires after Individual→Organization account conversion — no token, no error, app‑wide
Summary: After converting our Apple Developer account from Individual → Organization, our app stopped receiving APNs device tokens. application(:didRegisterForRemoteNotificationsWithDeviceToken:) is never called, and application(:didFailToRegisterForRemoteNotificationsWithError:) is also never called — no token, no error. This affects all new device‑token registrations app‑wide; device tokens issued before the conversion still work and continue to deliver pushes. Environment Membership status: Active Device: iPhone 15 Pro, iOS [26.6] Reproduced on both development (sandbox) builds installed via Xcode/CLI and TestFlight builds. What works Existing device tokens (created before ~Aug 1) still deliver pushes normally (server reports delivered 1/1 via our .p8 token‑based auth). So the send path and APNs auth key are fine. UNUserNotificationCenter authorization succeeds — authorizationStatus == .authorized. UIApplication.shared.isRegisteredForRemoteNotifications == true. What doesn't work We call UIApplication.shared.registerForRemoteNotifications() on the main thread after authorization is granted, but neither delegate callback ever fires — no token, no error — on any new install/launch. Timeline / trigger Everything worked before the Individual→Organization conversion. Since the conversion, no new APNs device token has been issued for the app at all. Server‑side we can confirm the most recent device token was created 2026‑08‑01, and none since, despite many fresh installs/launches across multiple users. Pre‑conversion tokens still function. What we've already tried / ruled out App ID has Push Notifications capability enabled; regenerated provisioning profiles. Generated a new APNs Auth Key (.p8) (sends already work, so this was expected not to matter). Fixed the Xcode signing team (it briefly showed "Unknown Name (TEAMID)" right after conversion; resolved by signing into the correct org account — Team now resolves correctly). Device reboot, network settings reset, app delete/reinstall, latest iOS. Confirmed delegate is wired (@UIApplicationDelegateAdaptor) — the same code issued tokens fine before the conversion. Thanks in advance!
0
0
378
Aug ’26
Push notifications not received despite HTTP 200 from APNs — seeking help to identify the cause
We're experiencing an issue where push notifications are not being received on certain iOS devices, and we'd like help identifying the possible causes. What we've confirmed so far: Push notifications are sent from our own provider server to APNs. APNs returns a normal response (HTTP/2 200) The device tokens are valid and up to date. Affected users have confirmed that notifications are enabled for our app in Settings. Users report no network connectivity issues. We are sending with apns-priority: 10 and apns-push-type: alert. Scope: This is occurring for multiple users, not isolated to a single device. It happens intermittently — some notifications from the same campaign reach the device, while others don't. Critically, some affected users report that they only fail to receive notifications from our app during certain specific time windows, while notifications from other apps arrive normally during the same period. This suggests the issue is app-specific and time-correlated, rather than a device-wide or network-level problem. Questions we'd like help with: Given that APNs returns 200, are there known scenarios where the notification still doesn't reach the device? (e.g., Focus / Do Not Disturb, low power mode, high-frequency throttling, stored-then-discarded due to apns-expiration) Is there a recommended way to obtain per-notification delivery status in the production environment? Are there known limits on how many notifications can be sent to the same device within a short window before APNs starts throttling or coalescing them? Our server logs currently do not retain the apns-id returned by APNs. If we provide the affected device tokens along with the approximate send timestamps, would it be possible for Apple to help investigate the delivery status of those notifications on the APNs side? Any guidance or pointers to relevant documentation would be greatly appreciated. Thank you!
5
0
784
Aug ’26
APNs sandbox: Has HTTP/2 request-rejection behavior changed?
Beginning July 29, 2026, we noticed a higher number of error responses from api.sandbox.push.apple.com: http2: server sent GOAWAY and closed the connection; LastStreamID=2147483647; ErrCode=PROTOCOL_ERROR; debug="Stream 3 does not exist for inbound frame DATA, endOfStream = true" The errors: Occur across multiple independent applications and regions. Are concentrated on the APNs sandbox endpoint. Did not coincide with a deployment or configuration change in our service. Were not accompanied by other typical failures such as 400 BadDeviceToken. Also increased on the APNs production endpoint, though the large majority remain concentrated on the sandbox endpoint. Could Apple confirm whether APNs recently changed how notification requests are validated or rejected, particularly in the sandbox environment? We can provide exact UTC timestamps, source regions, request metadata, and logs privately if needed.
5
1
975
Aug ’26
Push notification not send due to netowrk related errors
Beginning July 29, 2026, we observe communication erros while sending push notifications to https://api.push.apple.com like: Error in the HTTP2 framing layer Send failure: Connection reset by peer Also we ran tcpdump which clearly indicates that TCP RESET packets are coming from various APNS IP like 17.188.x.x. Errors mostly occure during traffic peak but also outside. We also did a test from different datacenter in other country and which resulted a same issue
0
1
774
Aug ’26
APNs VoIP push took 10 minutes to reach
I had strange experience few days ago. After sending VoIP push notification request properly to APNs it took nearly 10 minutes to actually receive the Push notification. Could this be cause by other than network issues? (i.e. APNs issue or iOS issue)
Replies
1
Boosts
0
Views
269
Activity
1d
Questions about VoIP Push compliance rules and CallKit handling
Hello everyone, I’m an iOS developer working on a real-time communication app that supports VoIP calls using CallKit. The app has been in production for more than 5 years. Over the years, some users have occasionally reported that they do not receive incoming call pushes. We have tried multiple optimizations on both the client and server side, but the improvement has been limited. From Apple documentation and discussions online, I understand that iOS may restrict VoIP pushes if the system detects violations of VoIP push usage rules (for example, not presenting a CallKit call after receiving a VoIP push). However, the exact rules and thresholds for these violations are not clearly documented, so I’d like to ask a few questions to better understand the expected behavior. Below is a simplified description of our current call flow. Call Flow Caller When the user initiates a call: We do not use CallKit The call is handled entirely using a custom in-app call UI Callee When the user receives a call: Device locked or app in background A VoIP push wakes the app The app presents the CallKit incoming call UI App in foreground The server still sends a VoIP push The app first reports the call to CallKit After a very short delay, the app programmatically ends the CallKit call Then a custom in-app call UI is presented via the app's long connection The reason we always send a VoIP push (even when the app is in the foreground) is that we want to maximize call delivery reliability.
Replies
7
Boosts
0
Views
1.1k
Activity
1d
AlarmKit: supported audio handoff for staggered overlapping alarms?
We can reproduce an AlarmKit audio failure on iPhone 16 Plus / iOS 26.6.2 (23G90) with a reduced SwiftUI app using fixed-date alarms and .default sound: Schedule three alarms at +60, +180 and +300 seconds. Leave the app visible and the phone untouched. The first alarm sounds. When the +180 alarm triggers, the +60 alarm is silenced (but still active). When the +300 alarm triggers, all three alarms will remain silent, however alarmUpdates reports one, then two, then three .alerting IDs. A single alarm in the same binary sounded continuously for at least 3 minutes 30 seconds. The reduced app has no custom intents, widget, countdown/snooze, audio session, background modes, notifications, packages or automatic cancellation. This exact reduced binary has one recorded comparison; earlier harness configurations also exhibited the failure. Sound was observed by the tester, separately from API logs. When +180 mutes +60, stopping the +60 alarm causes the +180 alarm banner to present itself and become audible. +300 triggering will then mute the +180 alarm. Likewise, stopping the +180 alarm will cause the +300 alarm to present itself and become audible. If you allow +60, +180, and +300 alarms to trigger without touching the screen, all three alarms will be silent at this point. Pressing "Stop" on +60 will cause the +180 banner to present itself and become audible, "Stop" on +180 will cause +300 alarm to then present and become audible. It is for these reasons that I believe there is a bug that occurs when an additional queued alarm transitions from "scheduled" to "active" status that causes the present active alarm to silence. In a foreground harness run, programmatically cancelling the +60 alarm's alerting ID caused the +180 alarm to sound. However that requires app execution and does not establish a background solution. The snooze/coincident-time report looks like it could be related. The FAQ's same-time scheduling answer also seems to describe a different case. What is the supported audio behavior when a later alarm becomes due while an earlier one remains alerting? Is there a scheduling or handoff pattern that preserves audible delivery without requiring the app to execute at each arrival? If overlap is unsupported, which documented constraints should applications follow? If anyone else has experienced this issue and has found a technical workaround I would appreciate hearing about it. For any Apple staff reading this, there is more information on this issue in Feedback Assistant ID FB24757864.
Replies
0
Boosts
0
Views
74
Activity
3d
Optimizing the Audio Ducking System: Solving the Lost Revenue Problem for the Apple Ecosystem and Third-Party Developers
Dear Apple Team, I am writing to propose an update to the audio management algorithms in iOS, specifically the automatic Audio Ducking feature during incoming notifications. The inability to disable this function not only creates daily discomfort for users but also directly harms the marketing effectiveness of both third-party services and the Apple ecosystem itself. Currently, the iOS architecture forces the user to choose between two scenarios, both of which are destructive to business: Damage to apps' marketing systems (if device sound is on) Music is a source of emotional pleasure and focus. When the system forcibly ducks the track's volume for a notification sound, users perceive it as an aggressive and annoying intrusion. Instead of engaging with the offer or message, the user feels negativity toward the sending app. The marketing tool (push notification) backfires: to protect their comfort, the user either dismisses the notification without looking or permanently revokes the app's notification permissions, destroying the communication channel and lowering engagement rates. 2. Damage to the reliability and reputation of the Apple ecosystem (if sound is off) Trying to avoid the annoyance described in the first point, the user resorts to the only available workaround — switching the iPhone to silent mode using the physical switch. However, after listening to music, this switch is often left in the silent position. Result: missed important calls, derailed work arrangements, or ignored emergency messages. In this scenario, Apple's reputation suffers. Because of the company's reluctance to add one simple audio focus setting, the device stops performing its core function as a reliable communication tool. The system literally forces the user to "cut" themselves off from the world for the sake of comfortable music listening, leading to negative real-world consequences. Proposed Solution: Introduce a toggle in the "Sounds & Haptics" (or "Accessibility") settings: "Do not duck media for notifications." Alternatively, allow notification sounds to play over the music without altering the main audio stream's volume. Apple has always been known for putting human comfort first. Adding this feature will solve a serious behavioral issue. It will preserve audience loyalty to third-party push campaigns and ensure that iPhone owners stop missing important life events due to the forced use of silent mode. Thank you for your time and attention to user experience. I hope this improvement finds its way into upcoming iOS updates. Sincerely, An Apple Ecosystem User
Replies
0
Boosts
0
Views
104
Activity
4d
LiveCommunicationKit: In‑call banner missing in foreground, only appears after app goes background (iPhone14 Pro)
Environment: Device: iPhone 14 Pro iOS version: 26 SDK: LiveCommunicationKit App status: Foreground / Active state Problem reproduction: Intermittent, happens on some devices, not 100% reproducible on all test devices. Expected behavior: Incoming call banner should present when app is active (foreground). Actual behavior: No system incoming‑call banner while app is foreground. Banner appears only after pressing home‑button / switching app to background. Additional notes: Our app uses LiveCommunicationKit because VoIP PushKit is not permitted for China mainland App Store distribution. Call reporting completes without error; no error returned from LiveCommunicationKit API. private func _lckReportIncomingCall(call: Call?, uuid: UUID, handle: String, hasVideo: Bool, displayName: String) { guard let manager = conversationManager else { Log.error("[ProviderDelegate-LCK] ConversationManager is nil, falling back") _fallbackReportIncomingCall(call: call, uuid: uuid, handle: handle, hasVideo: hasVideo, displayName: displayName) return } let callInfo = callInfos[uuid] let callId = callInfo?.callId ?? "" let remoteHandle = Handle(type: .generic, value: handle, displayName: displayName) let update = Conversation.Update(localMember: nil, members: [remoteHandle], activeRemoteMembers: [remoteHandle]) // 冷启动时 iOS PKPushRegistry 要求在 2 秒内上报来电,否则杀进程。 // Task { @MainActor } 是异步的,调试时主线程 RunLoop 来不及调度就超时了。 // 这里用 DispatchSemaphore 在后台线程同步等待 LCK 上报完成。 let semaphore = DispatchSemaphore(value: 0) var lckError: Error? DispatchQueue.main.async { Task { @MainActor in do { try await manager.reportNewIncomingConversation(uuid: uuid, update: update) Log.info("[ProviderDelegate-LCK] Reported incoming conversation: callId=\(callId), uuid=\(uuid)") if TelecomManager.shared.endCallkit { CoreContext.shared.doOnCoreQueue(synchronous: true) { core in let linphoneCall = core.getCallByCallid(callId: callId) if linphoneCall?.state == .PushIncomingReceived { try? linphoneCall?.terminate() } } } } catch { Log.error("[ProviderDelegate-LCK] Failed to report incoming conversation: \(error)") lckError = error } semaphore.signal() } } let waitResult = semaphore.wait(timeout: .now() + 5) if waitResult == .timedOut { Log.error("[ProviderDelegate-LCK] Timed out waiting for LCK report, falling back") _fallbackReportIncomingCall(call: call, uuid: uuid, handle: handle, hasVideo: hasVideo, displayName: displayName) } else if let error = lckError { Log.error("[ProviderDelegate-LCK] LCK report failed: \(error), declining SIP call") // 来电被拒(勿扰/黑名单等),decline 掉 SIP 侧 CoreContext.shared.doOnCoreQueue(synchronous: true) { _ in try? call?.decline(reason: .Busy) } } }
Replies
1
Boosts
0
Views
270
Activity
6d
AlarmKit on iOS 27 beta: alarmUpdates delivery deferred until app runs, stale re-presentation, audio without UI under Focus (FB23754550)
Feedback: FB23754550 (filed July 14, 2026, still Open, no response) App: AlarmWizard, com.UBSAnalyticsLLC.AlarmWizard, shipping on the App Store Device: iPhone 17 Pro Max Current OS: iOS 27.0 (24A5408d). First seen on iOS 27.0 Seed 3 (24A5380h). Still reproducing on 24A5408d as of September 2, 2026. Baseline: same app binary on iOS 26 release, same hardware, behaved correctly. No iOS 26 production user has reported any of the behaviors below. Alarm under test: Alarm.Schedule.Relative, Mon through Fri, 07:05 America/New_York. The app writes a timestamped file log of every AlarmManager.alarmUpdates emission, every BGTaskScheduler execution, and every scheduling call. All times below come from that log unless noted. ISSUE 1: alarmUpdates .alerting transition is not delivered while the app is suspended. It queues until the app next gets runtime. On iOS 26 the observer received .alerting at the scheduled minute with the app suspended (logged May 1 and May 6 at 06:35, the exact fire time). On iOS 27 the transition arrives only when the app next runs, almost always at unlock. Delivery lag for the 07:05 occurrence: Jun 15: observed 08:50 (+1h 45m, unlock) Jun 22: observed 09:15 (+2h 10m, unlock) Jun 23: observed Jun 24 02:56 (+19h 51m, BGProcessingTask woke the app) Jun 26: observed 17:22 (+10h 17m, unlock) Jun 30: observed 12:12 (+5h 07m, unlock) Jul 6: observed 09:08 (+2h 04m, unlock) Jul 7: observed 09:00 (+1h 55m, app opened) Jul 9: observed 07:06 (+81s, user unlocked right after dismissing) The lag always equals time-until-the-app-next-ran, across three app builds. The Jun 23 case crossed midnight, so the event landed on the next calendar day. Expected: .alerting delivered at or near fire time as on iOS 26, or documentation stating delivery is deferred to app runtime. Actual: delivery deferred up to about 20 hours. ISSUE 2: the system alarm UI re-presents an occurrence hours after its scheduled time. Jun 15: the 07:05 occurrence presented (lock screen alert with Snooze and slide-to-stop, plus sound) at 08:49. Lock screen screenshot attached to the FB. Jun 30: the 07:05 occurrence presented at 14:25. Paired screenshots from the same minute show the system alert ("Work Week", 2:25) next to the app's full alarm list (a disabled 5:45 AM and the 7:05 AM Work Week alarm, nothing near 14:25). The observer logged alerting to scheduled at 14:25:48. Expected: an alarm presents once, at its scheduled time. Actual: stale re-presentation up to 7+ hours late, and presentation of a disabled alarm. ISSUE 3: with a Focus (Do Not Disturb) active, the alarm played audio with no lock screen presentation. Jul 7, DND on overnight. At 07:05 the alarm sound played but no lock screen alarm UI appeared, only the indicator in the Dynamic Island. There was no way to stop it from the lock screen. Opening the app showed the alarm still in .alerting (our in-app firing UI appeared and the user stopped it there at 09:00). Expected: full presentation (UI and audio) breaking through Focus, per AlarmKit's stated purpose. Actual: audio only, no lock screen UI. ISSUE 4 (corroborating, no timestamped log): an AlarmKit countdown timer (AlarmManager.AlarmConfiguration.timer) presented its alert with no audio. The inverse of Issue 3. Presentation and audio appear to fire independently on iOS 27. HOW WE ISOLATED THE OS The identical binary ran on iOS 26 through early June with on-time delivery and no phantom presentations. The device was upgraded to the iOS 27 beta mid-June with no app change and the first stale presentation occurred Jun 15. Several internal builds since, including hardening for late delivery, changed nothing about the delivery lag. Every anomaly was checked against the log. Several suspected framework bugs were traced to our own code and fixed and are not reported here. In every case above, the log shows the app was suspended and received no callback at the relevant time, so the presentation, audio, and delivery behavior originated in the system. ATTACHED TO FB23754550: three production log exports (Jun 22 through Jul 9), the Jun 15 and Jun 30 lock screen screenshots, and a sysdiagnose captured Jul 14 (sysdiagnose_2026.07.14_19-19-40-0400_iPhone-OS_iPhone_24A5380h). I can capture a fresh sysdiagnose on 24A5408d immediately after the next occurrence if a targeted profile would help. Questions for Apple: Is deferred alarmUpdates delivery while suspended intended on iOS 27? If so, where is it documented, and what is the supported way to react to an alarm firing while the app is not running? Is there any known issue covering re-presentation of past occurrences? Is the Focus behavior in Issue 3 a known regression? With the iOS 27 RC expected this month, I would appreciate confirmation that this is on someone's radar.
Replies
2
Boosts
0
Views
198
Activity
1w
registerForRemoteNotifications gives neither a token nor an error for one bundle ID in production; development-signed build registers instantly
On a single device, a production-entitlement build of our app calls -[UIApplication registerForRemoteNotifications] and neither delegate callback is ever invoked. Not application:didRegisterForRemoteNotificationsWithDeviceToken:, and not application:didFailToRegisterForRemoteNotificationsWithError:. We wait 10 seconds and get nothing, on every launch, over more than 24 hours. UNAuthorizationStatus is .authorized, verified programmatically at the moment of the call rather than just in Settings, and the installed binary carries aps-environment = production, read off the device. The identical source signed with aps-environment = development receives a token in under one second on that same handset. We have isolated it to one cell of a four-way matrix. Production entitlement on this device: no token, no error, reproducing on both the App Store and TestFlight builds. Development entitlement on this device: token in under one second. Production entitlement on other devices: works, and other users register daily. Production APNs for other apps on this device: works, other App Store apps receive push normally. Already ruled out: notification authorization; the entitlement; delegate wiring (UIApplicationDelegateAdaptor is attached, and that same delegate receives the token when the app is development-signed); delete and reinstall from both the App Store and TestFlight; Reset Network Settings; reboot; airplane-mode cycle; an alternate network. Device context: iPhone 12 Pro (iPhone13,3) on iOS 26.6.1 (23G83). It is an AppleCare replacement unit, restored from a backup of the previous handset. Our working theory is stale per-app push registration state carried across in that restore, since reinstalling does not clear it, which suggests whatever is stuck does not live in the app container. Filed as FB24525199 with a sysdiagnose captured while the APNs logging profile was installed. Two questions. First, is there any way to force a device to discard and re-provision its per-app APNs registration state, short of erasing and setting up as new? Second, is the absence of both callbacks a known state? Every reference I can find treats didFailToRegisterForRemoteNotificationsWithError as the guaranteed path when registration cannot complete, so silence from both leaves an app with no signal to act on and no way to tell the user what is wrong.
Replies
5
Boosts
0
Views
197
Activity
2w
APNs proper behavior when connections are reset without warning
The company I work for sends large amount of traffic to APNs on behalf of our customers, with rates up to 50k/second at peek times. While a vast majority of the messages are successful or return a proper error code that we can parse and honor, roughly 1.5 million times per day our connections are being closed without warning. The networking library we use, https://github.com/hyperium/h2, is exposing these as ErrorKind::ConnectionReset or ErrorKind::BrokenPipe. From our reading of the APNs documentation, it is unclear what the correct response is when this occurs. There is no idempotency key included with our messages, so attempting to resend the message again seems frought with the potential for double sends. However, it some cases it seems clear that at least some of the messages in flight over that connection where never sent out at all. We found this open source project unconditionally retrying messages in this case. https://github.com/rpush/rpush/pull/734 Could someone from the APNs team please lay out the expected behavior a client should have when our connection is unexpected closed in this manner?
Replies
0
Boosts
0
Views
132
Activity
2w
Removing an unrelated AccessorySetupKit device invalidates notification forwarding sessions for accessories from another app
We are seeing a cross-app session-isolation issue involving DeviceAccess / AccessorySetupKit and Accessory Notifications. Setup: Garmin Connect owns an authorized Forerunner 745. Our app owns an Amazfit Active 3 Premium and an Amazfit Bip Max. Both Amazfit devices have working NotificationsForwarding DAExtensionSession instances. Reproduction: Keep notification forwarding working for the Amazfit devices, then forget the Garmin Forerunner 745 in iOS Settings > Bluetooth. DeviceAccess correctly removes only the Garmin device and emits DeviceLost for Garmin DeviceID C175AA77-... (com.garmin.connect.mobile). In the same millisecond, usernotificationsd invalidates two unrelated NotificationsForwarding sessions: CID 0x2D07001D, DeviceID 13D01E46-..., BundleID com.huami.watch CID 0x2D07001C, DeviceID D86C37A0-..., BundleID com.huami.watch The second session belongs to Bip Max. About four seconds later, notifications fail with: post() failed: no connection hasExtensionSession: false Bip Max remains Authorized and BTPaired, and its DADevice and notification capability remain present. Only its usernotificationsd-held NotificationsForwarding DAExtensionSession is lost. usernotificationsd also logs AccessoryNotifications.AccessoryError Code=5 while clearing the Garmin accessory record. Should DeviceLost ever invalidate NotificationsForwarding sessions with a different DeviceID and owning app? Is there a supported way to rebuild the missing session without removing and re-authorizing the retained accessory? Timestamp: 2026-08-31 14:08:46.973 local time. Full identifiers, tokens, and logs are omitted; we can provide a sysdiagnose and log archive through Feedback Assistant.
Replies
0
Boosts
0
Views
159
Activity
2w
APNs 410 Unregistered Spike and Invalid Token Behavior
Hello Apple Developer Technical Support, We observed an unusual increase in APNs 410 Unregistered responses in our production iOS app between July 10 and July 24, 2026: Before July 10: approximately 1,500–5,000/day July 10–24: approximately 15,000–30,000/day, a 5–10x increase After July 24: the volume stabilized and did not continue to increase We found no relevant changes to our client, server, or APNs configuration during this period, and no corresponding increase in 403 ExpiredProviderToken or 400 BadDeviceToken. We also found that the last app-open dates of the affected tokens were broadly distributed from August 2025 to June 2026, with no clear concentration around a specific inactivity period. We are not using 410 Unregistered as an uninstall signal. Our main concern is understanding why the response volume increased so significantly during this specific period. Could Apple confirm: Whether there were any APNs-side changes, maintenance activities, or changes in token processing behavior between July 10 and July 24 that could explain this increase? For a device token that becomes invalid due to app uninstallation, after how many push attempts would APNs typically return a 410 Unregistered response? Is it expected to return 410 on the first push attempt, or only after multiple push attempts?
Replies
0
Boosts
0
Views
226
Activity
2w
Multi-accessory DeviceAccess routing issues: notification sessions invalidated and replies wake the wrong Transport
Title: Multi-accessory DeviceAccess bugs: wrong PeripheralID in Transport wake-up; cross-device NotificationsForwarding session invalidation Topic: App & System Services → Core OS Tags: Core Bluetooth, AccessorySetupKit, Notifications Body: Context: our app uses AccessorySetupKit and a DeviceAccess-based accessory Transport + DataProvider extension pair (one shared extension bundle serves all accessories). Everything works with a single bound accessory, but with two or more ASK accessories on the same app we consistently hit two independent system-level failures. Both fail BEFORE any app callback runs (no DataProvider addNotification, no Transport messageReceived), so this is not app-side parsing or business logic. Tested on iPhone 11 Pro, current iOS 26 release; full logarchives available and can be attached to a Feedback Assistant case. Problem 1 — Transport wake-up requests use the wrong PeripheralID (uplink: watch reply → iPhone) Reproducible timeline from bluetoothd/deviceaccessd logs: Device A's GATT indication reaches bluetoothd; CoreBluetooth routes it to device A's CoreBluetooth session (its Transport PID). ~8 ms later, the DAExtensionRuntimeAssertion that bluetoothd sends to deviceaccessd carries device B's PeripheralID instead of device A's. deviceaccessd then resumes/updates device B's Transport. Device A's Transport stays suspended and never receives the data; the reply is lost. Two outcomes depending on whether the wrongly-used PeripheralID still resolves: Belongs to another still-bound accessory: the assertion "succeeds" and the wrong Transport instance is resumed — no error at all. Belongs to an already-removed accessory: DAErrorDomain 350002 "device not found". So the absence of error 350002 does not mean the mapping is correct. Re-authorizing the affected accessory via ASK does NOT repair the mapping: after re-ASK, notification delivery works again, but once the new Transport suspends, subsequent wake-ups still carry the other accessory's PeripheralID. Problem 2 — NotificationsForwarding DAExtensionSession lifecycle is not isolated per DeviceID (downlink: iPhone notification → watch) Expected: usernotificationsd holds one NotificationsForwarding DAExtensionSession per authorized accessory with notification forwarding enabled, strictly isolated by DeviceID. Observed instead: A session is "activated and stored" and then immediately invalidated by usernotificationsd itself, with no user action (four-accessory setup, three forwarding-capable). Any accessory's DeviceLost invalidates OTHER accessories' sessions. Logs show the event DeviceID differs from the invalidated session's DeviceID. This also happens when the removed accessory does not support notification forwarding at all (so there was no session of its own to clean up). After such mass invalidation, usernotificationsd may rebuild only some sessions or none — even when BLE, Transport, and DataProvider capability fully recover (e.g. after toggling Bluetooth). Notifications then stop at "post() failed: no connection (hasExtensionSession: false)". A new accessory's ASK DeviceFound triggers a rescan that rebuilds missing sessions for the older devices (consistent across our samples, but we don't know whether this is a stable contract). What we ruled out on our side: ASAccessorySession.removeAccessory is called with the correct target; nothing in the app touches other accessories' sessions or permissions. The failures happen inside system daemons before app callbacks; single-accessory flows work fine with identical code. Multiple DataProvider DAExtension records sharing one host PID behaved normally — expected ExtensionKit hosting, not the issue. Questions: Is the PeripheralID substitution in the bluetoothd → deviceaccessd DAExtensionRuntimeAssertion a known issue when one transport extension bundle serves multiple accessories? Any supported workaround? Should usernotificationsd session maintenance be strictly isolated by DeviceID? Is there a supported way to force-rebuild all NotificationsForwarding DAExtensionSessions without unbinding accessories? Is the DeviceFound-triggered full session rescan/rebuild a contract we may rely on? Happy to provide logarchives and detailed timelines via Feedback Assistant. Thanks!
Replies
0
Boosts
0
Views
291
Activity
2w
FCM Token Not Receiving Notifications Despite Successful Token Retrieval on iOS
We are facing an issue with push notifications on our iOS production application and would appreciate guidance. Issue Summary Push notifications were working correctly previously but stopped working around two weeks ago. We use Firebase Cloud Messaging (FCM) for push notifications, which delivers notifications to our iOS application through APNs. The issue appears to be related to existing FCM tokens. Existing FCM Token We have an FCM token already stored in our production backend database. When we try to send a notification using this token: Our backend sometimes receives the following response: { "error": { "code": 404, "message": "NotRegistered", "status": "NOT_FOUND", "details": [ { "@type": "type.googleapis.com/google.firebase.fcm.v1.FcmError", "errorCode": "UNREGISTERED" } ] } } In some cases, the API request appears successful, but the notification is still not received on the iPhone. We also copied the exact same existing token and tested it directly using Firebase Console → Send test message. The notification was not received on the device. Newly Generated / Retrieved FCM Token We then generated/retrieved the FCM token again from the same application and tested it directly from Firebase Console. Using the newly retrieved token: The notification was successfully received on the same iPhone. This means the following behaviour is observed: Existing FCM Token ↓ Backend may return 404 UNREGISTERED OR Firebase may accept the send request ↓ Notification not received But after retrieving the token again: FCM Token Retrieved Again ↓ Firebase Console Test ↓ Notification received successfully Client-Side Configuration We have confirmed the following: APNs device token is successfully generated. FCM registration token is successfully generated. Notification permission is granted. The application is connected to the correct Firebase project. FirebaseAppDelegateProxyEnabled is set to NO. Since Firebase method swizzling is disabled, we manually assign the APNs token to Firebase Messaging. Our APNs registration code is: func application( _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data ) { print("*** APNS Device Token: ", deviceToken) Messaging.messaging().apnsToken = deviceToken Messaging.messaging().subscribe(toTopic: "testing_new_events") { error in if let error = error { print("*** Failed to subscribe: \(error.localizedDescription)") } else { print("*** Subscribed to topic successfully") } } } Main Question About the 404 UNREGISTERED Response One part of this behaviour is particularly confusing to us. If Firebase returns: 404 UNREGISTERED NotRegistered for a particular FCM token, we would expect that token to be invalid and that the application should receive or generate a completely new FCM registration token. However, when we retrieve the FCM token again from the application, Firebase may return the same token value again. Our question is: If Firebase considers an FCM token unregistered and returns 404 UNREGISTERED when sending a notification, why can Messaging.messaging().token() or the token callback still return the same token again instead of generating a new token? For example: Token A stored in backend ↓ Backend sends notification ↓ FCM returns 404 UNREGISTERED ↓ App retrieves FCM token again ↓ Firebase returns Token A again We would like to understand whether this is expected behaviour. Specifically: Does UNREGISTERED always mean that the locally cached FCM token should immediately be replaced with a new token? If not, why can the same FCM token still be returned to the application after Firebase returns UNREGISTERED for it? Is there a delay between Firebase invalidating a registration for sending and the client generating a replacement token? Is there a recommended way to force Firebase Messaging to refresh or re-register an FCM token after receiving UNREGISTERED? Could the token be cached locally even though its server-side registration is no longer valid? Additional Questions We would also appreciate guidance on the following: Is it possible for an existing FCM token to become stale or no longer usable for notification delivery without immediately returning an UNREGISTERED error for every send attempt? Can Firebase accept a message for an existing token and return a successful response, while the notification is never delivered to the device? On iOS, could the relationship between an existing FCM token and its APNs token become invalid or stale, while the application still returns the same FCM token? Is there any APNs-side reason why an old FCM token would stop receiving notifications while a newly generated/retrieved token on the same device receives notifications successfully? What is the recommended client-side and backend-side handling after receiving a 404 UNREGISTERED response? Should we immediately remove the token from our database and wait for the application to register a new token? Our main concern is understanding why an FCM token can receive a 404 UNREGISTERED response during sending, but the application can still return the same token when we attempt to retrieve it again. Any guidance on whether this behaviour is expected, particularly regarding the interaction between FCM token registration and APNs on iOS, would be greatly appreciated.
Replies
0
Boosts
0
Views
237
Activity
2w
Any options for automated testing of notifications?
My app uses a notification service extension and a notification content extension, both of which are considerably complex and result in a few different dozen combinations of notification with various layouts and content. Regression testing of all the multitude of combinations of notifications is time consuming. Is there any tools available that can utilized to create a test harness? I was thinking something like the test harness sends a series of pushes and each resulting notification gets checked. Is XCUITest capable of verifying the content/layout of notifications? If so how could XCUITest be incorporated with a test harness that is driving things and sending the pushes etc.
Replies
0
Boosts
0
Views
133
Activity
3w
Push Notification Icon Not Updated on Some Devices After App Icon Change
Hi, We recently updated our app icon, but the push notification icon has not been updated on some devices. It still shows the old icon on: • iPhone 16 Pro — iOS 26 • iPhone 14 — iOS 26 • iPad Pro 11” (M4) — iOS 18.6.2 • iPhone 16 Plus — iOS 18.5 After restarting these devices, the push notification icon is refreshed and displays the new version correctly. Could you advise how we can ensure the push notification icon updates properly on all affected devices without requiring users to restart? Thank you.
Replies
5
Boosts
3
Views
1.8k
Activity
3w
Production APNs rejects a valid production device token with BadEnvironmentKeyInToken (newly released app)
My app was approved and released on the App Store on Aug 19, 2026 (bundle ID br.com.stackads.app, Team ID MSGM29Z362). Push notifications do not work on the production/App Store/TestFlight build. Android via FCM works fine; only iOS production APNs fails. It has been more than 48 hours since release. I captured the raw APNs device token directly from application(_:didRegisterForRemoteNotificationsWithDeviceToken:) in a production (App Store distribution) build (aps-environment = production, verified in the built .ipa entitlements). Sending directly to APNs with a token-based .p8 auth key (Key ID VXXXXXXX, Team ID MSGM29Z362), apns-topic br.com.stackads.app, apns-push-type alert, returns: api.push.apple.com (production): HTTP 403 {"reason":"BadEnvironmentKeyInToken"} api.sandbox.push.apple.com (sandbox): HTTP 400 {"reason":"BadDeviceToken"} The provider (JWT) authentication succeeds (I get a device-token error, not an auth error), so the key is valid. The App ID has the Push Notifications capability enabled. The token is freshly registered (confirmed identical between the didRegister callback and getAPNSToken). Why does the production APNs endpoint reject a valid production device token for this App ID with BadEnvironmentKeyInToken? Is there something pending in the production APNs provisioning for a newly released App ID?
Replies
0
Boosts
0
Views
233
Activity
3w
didRegisterForRemoteNotificationsWithDeviceToken never fires after Individual→Organization account conversion — no token, no error, app‑wide
Summary: After converting our Apple Developer account from Individual → Organization, our app stopped receiving APNs device tokens. application(:didRegisterForRemoteNotificationsWithDeviceToken:) is never called, and application(:didFailToRegisterForRemoteNotificationsWithError:) is also never called — no token, no error. This affects all new device‑token registrations app‑wide; device tokens issued before the conversion still work and continue to deliver pushes. Environment Membership status: Active Device: iPhone 15 Pro, iOS [26.6] Reproduced on both development (sandbox) builds installed via Xcode/CLI and TestFlight builds. What works Existing device tokens (created before ~Aug 1) still deliver pushes normally (server reports delivered 1/1 via our .p8 token‑based auth). So the send path and APNs auth key are fine. UNUserNotificationCenter authorization succeeds — authorizationStatus == .authorized. UIApplication.shared.isRegisteredForRemoteNotifications == true. What doesn't work We call UIApplication.shared.registerForRemoteNotifications() on the main thread after authorization is granted, but neither delegate callback ever fires — no token, no error — on any new install/launch. Timeline / trigger Everything worked before the Individual→Organization conversion. Since the conversion, no new APNs device token has been issued for the app at all. Server‑side we can confirm the most recent device token was created 2026‑08‑01, and none since, despite many fresh installs/launches across multiple users. Pre‑conversion tokens still function. What we've already tried / ruled out App ID has Push Notifications capability enabled; regenerated provisioning profiles. Generated a new APNs Auth Key (.p8) (sends already work, so this was expected not to matter). Fixed the Xcode signing team (it briefly showed "Unknown Name (TEAMID)" right after conversion; resolved by signing into the correct org account — Team now resolves correctly). Device reboot, network settings reset, app delete/reinstall, latest iOS. Confirmed delegate is wired (@UIApplicationDelegateAdaptor) — the same code issued tokens fine before the conversion. Thanks in advance!
Replies
0
Boosts
0
Views
378
Activity
Aug ’26
Push notifications not received despite HTTP 200 from APNs — seeking help to identify the cause
We're experiencing an issue where push notifications are not being received on certain iOS devices, and we'd like help identifying the possible causes. What we've confirmed so far: Push notifications are sent from our own provider server to APNs. APNs returns a normal response (HTTP/2 200) The device tokens are valid and up to date. Affected users have confirmed that notifications are enabled for our app in Settings. Users report no network connectivity issues. We are sending with apns-priority: 10 and apns-push-type: alert. Scope: This is occurring for multiple users, not isolated to a single device. It happens intermittently — some notifications from the same campaign reach the device, while others don't. Critically, some affected users report that they only fail to receive notifications from our app during certain specific time windows, while notifications from other apps arrive normally during the same period. This suggests the issue is app-specific and time-correlated, rather than a device-wide or network-level problem. Questions we'd like help with: Given that APNs returns 200, are there known scenarios where the notification still doesn't reach the device? (e.g., Focus / Do Not Disturb, low power mode, high-frequency throttling, stored-then-discarded due to apns-expiration) Is there a recommended way to obtain per-notification delivery status in the production environment? Are there known limits on how many notifications can be sent to the same device within a short window before APNs starts throttling or coalescing them? Our server logs currently do not retain the apns-id returned by APNs. If we provide the affected device tokens along with the approximate send timestamps, would it be possible for Apple to help investigate the delivery status of those notifications on the APNs side? Any guidance or pointers to relevant documentation would be greatly appreciated. Thank you!
Replies
5
Boosts
0
Views
784
Activity
Aug ’26
I didn't receive any push notifications from apns on my iPhone
What I found during the development: The Apple phone has registered the device token and it is within the validity period, but it cannot receive the apns message. However, only after I re-registered the device token with this token could this iPhone receive apns push notifications normally... What's going on here? How can it be optimized?
Replies
1
Boosts
0
Views
484
Activity
Aug ’26
APNs sandbox: Has HTTP/2 request-rejection behavior changed?
Beginning July 29, 2026, we noticed a higher number of error responses from api.sandbox.push.apple.com: http2: server sent GOAWAY and closed the connection; LastStreamID=2147483647; ErrCode=PROTOCOL_ERROR; debug="Stream 3 does not exist for inbound frame DATA, endOfStream = true" The errors: Occur across multiple independent applications and regions. Are concentrated on the APNs sandbox endpoint. Did not coincide with a deployment or configuration change in our service. Were not accompanied by other typical failures such as 400 BadDeviceToken. Also increased on the APNs production endpoint, though the large majority remain concentrated on the sandbox endpoint. Could Apple confirm whether APNs recently changed how notification requests are validated or rejected, particularly in the sandbox environment? We can provide exact UTC timestamps, source regions, request metadata, and logs privately if needed.
Replies
5
Boosts
1
Views
975
Activity
Aug ’26
Push notification not send due to netowrk related errors
Beginning July 29, 2026, we observe communication erros while sending push notifications to https://api.push.apple.com like: Error in the HTTP2 framing layer Send failure: Connection reset by peer Also we ran tcpdump which clearly indicates that TCP RESET packets are coming from various APNS IP like 17.188.x.x. Errors mostly occure during traffic peak but also outside. We also did a test from different datacenter in other country and which resulted a same issue
Replies
0
Boosts
1
Views
774
Activity
Aug ’26