PLATFORM AND VERSION: iOS Development environment: Other: .net MAUI with vscode Run-time configuration: iOS 18.1.1
DESCRIPTION OF PROBLEM APNS notifications of apns-push-type pushtotalk sometimes stop arriving after switching networks.
STEPS TO REPRODUCE We have created a simple app which can be used to deminstrate this issue. When you launch the app it displays the APNS token which you can then use fromn the Apple Push Console to manually send it PTT push notifications.
https://github.com/trampster/PttPushNotificationIssue
On an iPhone SE (we havn't been able to reproduce on our iPhone 11)
- Start the APP to register for the APNS push notifications
- Turn off the WiFi wait for 5 seconds
- Attempt a push to the app manually using the Push Notifications Console (this should fail, which is fine)
- Turn on Cellular and wait for it to connect
- Attempt to push to the app manually using the Push Notifications Console
-> This fails, and all attempts to send an pushtotalk push notifications fail until the we switch network again.
Send a push while offline before connecting to the new network seems to make it happen more often but hard to tell for sure.
The results of the failed push in the console look like this:
Delivery LogLast updated: 30/01/25, 16:45:06 GMT+13 Refresh
30 Jan 2025, 16:45:03.661 GMT+13
received by APNS Server
30 Jan 2025, 16:45:03.662 GMT+13
discarded as device was offline
The device is actually very much online.
Switching networks again oftern makes things come right. But it doesn't seem to come right by itself.
We can't respond to network changes and do anything as the whole point of using push-to-talk push notifications is to wake up the app when in the background to answer a call, this means we are not running and therefore cannot respond to network changes to try to work arround this issue.
We hadn't realized that the APNS sandbox is expected to be lower reliability/performance.
As a small clarification, the term "expected" is complicated. The issues here isn't that we intentionally "want" the sandbox to be less reliable, it's that a whole lot of implementation details end up making that the practical result. In general terms, the main issue here is an interaction between three factors:
-
Architecturally, the production and sandbox connections are basically managed as parallel, independant "systems". Importantly, this means that the production and sandbox "notice" connection issues independently.
-
It's fairly common for a connection issue to be detected because of a device side "action". For example, launching an app may cause the system to verify it's push token using the same network connection used for push delivery.
-
The production system obviously has FAR more clients than the sandbox system.
Note that there isn't any really any good "solution" to any of these. The last case (#3) is basically just inevitable, as push is a very widely used technology. Entangling the implementation (#1) would make it more likely that we'd introduce new bugs/discrepancies between the two system, which is exactly what we were trying to avoid. Lastly, oart of the basic reality of networking is that you don't "know" whether or not something "works" until you "try", which is what creates (#2).
With all that context, I'd keep two things in mind:
-
The Push Notifications Console (which is sandbox only) does mean that you have better visibility into what actually happens to any given notification than you would in the production environment. So, a delivery failure may be more likely, but it's also somewhat easier to figure out "why" a given failure happened.
-
For a PTT/voip app where push is so critical, I would think of the push sandbox as "the place I test push/server changes", NOT "the place I test my app". Once you've finalized your push payload, shipped a working app, and/or stabilized your server, I think it's reasonable for most development and testing builds to use the production environment in the same way I'd expect those builds to use your production server. The sandbox environment would then be reserved for testing changes to your server and/or push payload format, in which case the reliability different doesn't really matter. I'd probably formalize this dynamic by having the server itself tell the client what push environment it should be using.
Obviously our actual customers are using the production environment. After testing with the production environment we are unable to reproduce this issue. This puts our minds at ease.
Good, that's exactly what I'd expected.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware