IPhone is not receiving silent push notifications via APNs properly - ios

we are trying to implement silent push notifications in our react native app. Unfornately we get some strange trouble with iOS. After all we could find 3 cases, where push notifications arent received at our test iPhones properly.
We have also tested our new feature on Android but apparently these issues only occur on iOS. We found the same question on stackoverflow (iOS Silent Push Notification not delivered after device reboot) but the answers were not quite helpful.
In our first case we discovered that the delivery of Push Notifications to multiple iPhones doesnt seem reliable. We tested this problem with 2 phones (iOS 15 + iOS 16), where one of them doesnt receive messages correctly. On the one hand the messages were not displayed after starting our app and on the other hand the notifications didnt show up at all. We couldnt find any reasons for that and we are pretty sure that React Native is not the problem here. We could only find this strange log:
"com.apple.pushLaunch.de.example.app:37D069:[{name: ApplicationPolicy, policyWeight: 50.000,
response: {Decision: Absolutely Must Not Proceed, Score: 0.00,
Rationale: [{[pushDisallowed]: Required:0.00, Observed:1.00},]}}
{name: BootTimePolicy, policyWeight: 0.010, response:
{Decision: Must Not Proceed, Score: 0.00,
Rationale: [{[Minimum seconds after boot]: Required:120.00, Observed:68.56},]}}
{name: , policyWeight: 1.000, response: {Decision: Must Not Proceed, Score: 0.00,
Rationale: [{timeSinceThunderingHerdTriggerEvent < 300}]}}],
FinalDecision: Absolutely Must Not Proceed}"
Our second problem occur when we send a push notification to an inactive phone. After sending the message and booting our phone, we are not able to receive the message at all except the user start the app. This problem always occur when the phone was off.
The third problem is quite similar to the second one. First we reboot our test device and send after that a push notification via APNS. The user will not receive any messages, if the app is not started. We could find this log:
"Daemon Canceling Activities: {(com.apple.pushLaunch.de.example.app:E7F648)}"
"CANCELED:com.apple.pushLaunch.de.example.app:E7F648 at priority 5 <private>!"
 
"com.apple.pushLaunch.de.example.app:71F21A:[
{name: ApplicationPolicy, policyWeight: 50.000, response:
{Decision: Absolutely Must Not Proceed, Score: 0.00,
Rationale: [{[pushDisallowed]: Required:0.00, Observed:1.00},]}}
{name: ThunderingHerdPolicy, policyWeight: 1.000, response:
{Decision: Must Not Proceed, Score: 0.00,
Rationale: [{timeSinceThunderingHerdTriggerEvent < 300}]}}],
FinalDecision: Absolutely Must Not Proceed}"
Our payload has only the content-availability header set to true. There is no other header specified in the payload. The response of the Apns is always 200.
All these problems seems to be an hotfix but we could not find any useful informations by apple. Any ideas would be very helpful.
For Android and iOS we use the react native libraries:
https://github.com/react-native-push-notification/ios
https://github.com/zo0r/react-native-push-notification

Related

Track when application is uninstalled on iOS

i have been trying to find a way to track when our app is uninstalled from iOS device :
Sending Push notification, this sometimes gives the desired 410 ( app uninstalled ) most of the time returns just 200. I could not find any examples on how to use their Feedback service, which seems obsolite.
Background pinging works only when the app is in the background but not shutdown. It probably could work if the app uses location services, but that would require more permissions.
Is there any way stable way to track this at all ?
many thanks
You can share your exact case to get alternative solutions.
BTW, The nearest technique to achieve this is:
1- Send silent notification, Check the following:
https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app
And Note the following:
The system treats background notifications as low-priority: you can
use them to refresh your app’s content, but the system doesn’t
guarantee their delivery.
2- Once you have received the notification in the device, call a web-service to flag this device/ user.
In case you want this for collecting insights, you can use analytical frameworks like: Google Analytics to get all insights that you want (Active, Downloaded, ...). Check the following:
https://developers.google.com/analytics/devguides/collection/ios/v3

IOS - Background receive notification

I'm looking at a way to receive (any form of) a notification in IOS (iPhone).
This is needed for a "nurse call" like project and should work regardless of internet connection.
But there are a few "small" restrictions.
It must work on a local network (no connection to the world wide web).
The app must work in background (not always opened).
The response time should be 1 minute max.
If it's of any help, I do have the possibility of using a local Apple MacOSX server.
Things I've tried.
I've looked at Apple Push Notifications, though I believe it will need access to the APNs (server). And can't work locally.
I've looked at keeping an "server" open in an IOS app, though this server will certainly be killed when the app is not in the foreground.
I've looked at the background mode "fetch", but it's not possible to set the frequency and it may just work once every 30 minutes.
I've looked at the Apple server, but I'd rather not use a local e-mail server since it's probably not fast enough and it'll not be possible to interact with an app this way.
The "Messages Server" seems to be interesting, but I'm not sure if I can receive those messages on an iPhone (from a local server, withouth the need of Apple servers).

iOS / Swift : Receive callbacks from data streaming service without push notifications while app is in background

The Background Information:
I am writing an application that uses the PubNub framework to directly couple one Raspberry Pi with one iPhone, for each individual user. The Raspberry Pi uses an Arduino as a slave to gather analog data, then uses the PubNub network to publish that data to the one and only iPhone that is on the same channel. With the data that the iPhone receives, it determines (locally) if the user needs to be alerted. Then, when the user is alerted, they have the ability to adjust the current state of the Raspberry Pi by sending data (settings) back to the Pi, which will then resolve the problem that warranted a user alert.
The Problem:
When the iPhone app goes into the background, the messages sent by the Raspberry Pi that the iPhone should be receiving will no longer be caught by the application, and therefor the user is no longer notified when they need to be. The first obvious solution would be to move the logic of what warrants an alert to the Raspberry Pi itself, so that it can use Apple Push Notifications to send those alerts to the user. However, the problem with this is that I am also trying to track whether or not the Raspberry Pi connection has timed out, so that if some unexpected disconnect occurs, the user is notified of that problem as well. This logic obviously can not be on the Raspberry Pi itself, because if a disconnect occurs, then it will not be able to push the notification to the iPhone itself. Having a middle man server of sorts to monitor the state of the device would seem like a logical solution... however I do not want anything other than the iPhone and Raspberry Pi involved in the data transmission and handling, which is clearly the entire motivation behind using PubNub in the first place (within the scope of my application).
This is not a PubNub specific problem. I only cite them to paint a clearer picture. Also worth noting is that I do not want to fake a location service in order to get iOS to grant continuous background permissions. This is a lazy and sloppy solution with undesired overhead.
The Question:
How do I receive (or request) a short string every 15 to 30 seconds in the background to determine if I should throw an alert. This has to be achievable. Based on my research and reading of apple documentation, it is clear to me that many people will try to respond with "it isn't possible." I do not welcome this answer. I am here to find a solution that I could not previously find, or that has not previously been proposed. I need an intelligent engineer to propose a genuine solution or workaround to my problem.
I sincerely thank the champion engineer in advance.
#JonW I read your question, and some of the comment until I got to the TL;DR point :) The short answer is that silent push notifications might be the answer to one of your problems.The other might be PubNub Presence Webhooks. But I would agree with #Paulw11 that a server is the best practice and ultimately, PubNub BLOCKS will be your solution.
Background Processing with Apple Silent Push Notifications
To do some short background processing, you can have your RPi publish a message that includes a push notification (as I believe you are already doing). But this push msg should be a silent push notification. The docs say this:
When a silent notification arrives, iOS wakes up your app in the
background so that you can get new data from your server or do
background information processing.
... ensure there is no alert, sound, or badge payload in the aps dictionary
The full details are at the link I just provided but here is a sample message payload that you would publish on PubNub with the proper aps format.
{
"pn_apns": {
"aps": {
"content-available": 1,
"data": {
"temperature": "55",
"humidity": "42%"
}
}
},
"data": {
"info": "This is the full realtime message.",
"temperature": "55",
"humidity": "42%"
}
}
WARNING: The silent push notifications are only effective if the app is not in a kill state. In other words, it must be idle in background - not running, but idle. If you force kill the app (swipe up from recent apps list by double tap Home button) or do not start the app after device has been powered off then on again, then silent pushes will be ignored.
See this Badge Count Demo as a template for getting started. But as #Paulw11 said, regular push notifications every 30 seconds is not a good idea. You should be sending your updates to a server that can send a push notification to the iPhone app when it is necessary to take action.
Offline Notification with PubNub Presence Webhooks
Going further down the server process best practice, you can have your server monitor the presence of the RPi on the channel. If the RPi ever leaves the channel by explicit unsubscribe from channel (leave event) or by network disconnect (timeout event), then a message can be POSTed to your server REST endpoint (that you provide us to configure on your PubNub keys). If either of these events happens, then you can publish a message (silent push payload included) to your iPhone app to take appropriate action.
PubNub BLOCKS - No Server Required (Look mom, no server!)
So you say you want to avoid using a server. With PubNub BLOCKS, you will be able to avoid using your own server - instead, you will use PubNub servers.
I won't into too much details here, but you will be able to write a small bit of JavaScript in a BLOCK that can determine if a push notification needs to be sent or not and much much more.
Summary
For now, I think your prototype with silent push is good to flesh out your use case. But ultimately, you need to have an always on process that can determine when it is necessary to send a push notification. While your iPhone app is active, it can receive the realtime messages from RPi, but when in background, getting a silent push every 30 seconds is not ideal and possibly not allowed by Apple.

Using a rate limit with Apple MDM

In our Apple MDM solution I would like to implement a rate limit, setting a limit on how many devices can interact with the server at any time.
Just like an iOS device responds with a NotNow when it is not able to service a request, I was thinking about responding with a 429 (Too Many Requests).
How would a device act upon receiving this? Would it try again a little later or would it just give up and wait for a new request?
a) You can try and see what will happen
b) Generally speaking, device behavior is unreliable (documentation doesn't specify how a device will behave in this case, so it can change from version to version)
c) Why do you have this problem at all? A device only attempts to receive a command when you send a push notification. So, instead of limiting who can get a command, just limit push notifications which you are sending.

Get messages from server in real-time

It's generally a common question.
I wonder how do mail apps implement functionality of email-receiving?
I need to implement a simple sync between two devices(for example) using my web service.
Imagine a to do list app.
Is it possible to implement such a functionality: device1 makes an entry,then sends a message to webservice, webservice informs device2 that changes took place and device2 adjusts its data and displays that entry?
On iOS what you want could easily be implement with push notifications.
As soon as the server detects changes that device2 needs to be aware of the server will send a push notification to that device.
After the user views the notification the app should update it self, it would also be a good idea to let the app update it self when coming to the foreground.
The reason for doing it with Push Notification and not polling is that if your app is in the background you can only continue to run a process for 10 min max. You might get around this by adding the background mode to your app, like VOIP, Audio or location. But if you app does not fall in those categories apple might reject your app.
With Push notification the device will receive the notification even if your app isn't running or in background.
Basically there are 2 ways:
polling, each device asks the webserver for changes every N minutes: new todo, delete a todo, change a todo, ... and then each device will adjust. The frequency of the poll depends of the level of real time you are looking for. It can be 1 call every second or every 12 hours or much more.
implement a kind of BOSH protocol: the device opens a connection to the server. The server keeps it open until there something new to send to the device or the connection times out. In that case, the device reopens it.
Option 1 is better for your todo app because you don't need real-time accuracy. The option 2 is better for a chat application where you don't want to wait for the message.

Resources