iOS silent push notification - ios

I am trying to implement silent push notification in my application where I need to update some data in the server when silent notification comes. I am using Pushkit and it uses VoIP certificate for silent push notification but the app has been rejectd by Apple saying that "I can't use VoIP" certificate. It seems that apple has rejected it as I don't have any VoIP call functionality in my app. In that case how can I implement silent push notification so that my app gets activated even if it is not runnning(not even in the background) and I can update the server?

From my experience, iOS respects user's choice, so in case the user has killed the app, it will remain killed - no silent push notification will wake this app. VoIP is an exception to that, but as you wrote, it should be used only in VoIP apps. This makes sense, consider it a platform limitation: thanks to that user have some control over what is actually running on the phone, the device consumes less battery and lastly, foreground/system Apps has the most CPU time to utilize.
There are few techniques to work with data in the background:
Content-available push notification: will wake up the application in case it is suspended, or startup it in case it has been killed by the system/crashed. Note, that this only opens a 30-second window and amount of notifications is throttled by APNS.
Background fetch capability will act in a similar manner.
Background task to finish existing task - but this is only used when app is moved to the background.
If you need App to send updates to the server, I believe above should be sufficient (unless your app is spying on a user, it should have all relevant data available once the user finishes interaction with the App).
If you need a server to send data to the App, use silent push notification (or background fetch for periodic pulling), or in case this data is critical to the user, you can present him a remote notification - if the user considers that an important update, he will open the app.

Related

Are silent notifications received with background notifications turned off, while application is running in iOS?

I just took a look at Is Silent Remote Notifications possible if user has disabled push for the app?.
It basically says the Silent Notifications disregard notification settings for user. It then says:
Users still have the ability to switch off your app’s ability to
process a “silent push” by means of the “Background App Refresh”
control. Even though Apple Push Notification service (APNs) will
deliver a push marked “content-available” to your phone, the OS will
not wake up your app to receive it, effectively dropping it on the
floor.
This is confusing to me. I want to make silent notifications go out only while the app is open, to update state of the app while in use only. So I wouldn't care if background app refresh is off because I wouldn't need to "wake up [my] app to receive it".
Secondarily Silent push notifications only delivered if device is charging and/or app is foreground talks about needing to have your phone plugged in to receive these notifications.
Both questions are from iOS 8, which is quite a ways back. Do they hold up all this time?
My answers are based on observation and my work on the apple notification.
Before iOS 13
Silent notification is not received even if notification is force killed by the user even if the background app refresh is on. Silent push received in case of foreground, background or killed by iOS
After iOS 13
Silent notification are received always if background app refresh is on.But if background app refresh is off silent push received only in foreground and background case.
If you want to only send silent push in foreground or background you should not add background mode in capability in Xcode. So it will receive only when the application is in the foreground or background

How to wake up a not running app when receiving remote notifications

Right now I have a framework that receives a silent notification, get the data from it (custom data) and translate it into a local notification to show the alert to the user (this is donde in didReceiveRemoteNotification:fetchCompletionHandler method). I have implemented this framework on an app and everything seems to be working correctly, silent notifications are being process when the app is in background and foreground. However, when the app is killed by the user or it is not running, I cannot receive notifications because of this:
Use this method to process incoming remote notifications for your app.
Unlike the application:didReceiveRemoteNotification: method, which is
called only when your app is running in the foreground, the system
calls this method when your app is running in the foreground or
background. In addition, if you enabled the remote notifications
background mode, the system launches your app (or wakes it from the
suspended state) and puts it in the background state when a remote
notification arrives. However, the system does not automatically
launch your app if the user has force-quit it. In that situation, the
user must relaunch your app or restart the device before the system
attempts to launch your app automatically again.
The reason I use this method for showing notifications is because the payload I sent to APNS has custom data with key-values that indicate how the notification must behave.
I've been doing some research and I found that Pushkit for VoIP can do the job. However, many post suggest that this can cause app rejection.
So my question is, how can I achieve receiving remote notifications even if my app was killed and considering that data in the payload has custom information to build the notification?
Silent push notifications are unreliable: they might get delayed, delivered in groups or even not delivered at all.
If you need to modify the content of the notification before presenting a banner for the user, you should use a Notification Service App Extension. You can also share some information between your app and this extension - using app groups or the keychain - if it needs something from your app to process the notification data.

Difference between voip push and regular push when waking app from background

I have a messaging service that I use for regular push notifications. For example, when one user sends a message, the other user receives a push notification with that message. I have noticed if the phone is on wifi and 3g / 4g, and the app is killed (and the screen is locked), the notification will be received. If the device is only on wifi and the app is killed (and the screen is locked), the notification is not received.
My assumption is that in order to conserve battery, the device disconnects from wifi after a certain time, and that is why push notifications are not received.
But when I use VOIP push notifications, the situation is different. Even if the app is killed and the device is on wifi (and the screen is locked), the notification will be received. So what does this mean? How is phone receiving this notification, if it disconnects from wifi?
What am I missing here?
Furthermore, to add to Sivajee Battina's answer, this is what you can read in the guidelines:
There are many advantages to using PushKit to receive VoIP pushes:
The device is woken only when VoIP pushes occur, saving energy.
Unlike standard push notifications, which the user must respond to before
your app can perform an action, VoIP pushes go straight to your app
for processing.
VoIP pushes are considered high-priority notifications
and are delivered without delay.
VoIP pushes can include more data than what is provided with standard push notifications.
Your app is automatically relaunched if it’s not running when a VoIP push is received.
Your app is given runtime to process a push, even if your
app is operating in the background.
So the third point confirms that your standard push notifications can be delayed in certain circumstances, while VoIP push notifications will always be delivered instantly.
Also, have a look at this question for reasons why standard push notifications are delayed or dropped.
You are almost correct in this - this is how voIP works. Excerpted from Apple Docs:
In the past, a VoIP app had to maintain a persistent network
connection with a server to receive incoming calls and other data.
This meant writing complex code that sent periodic messages back and
forth between the app and the server to keep a connection alive, even
when the app wasn’t in use. This technique resulted in frequent device
wakes that wasted energy. It also meant that if a user quit the VoIP
app, calls from the server could no longer be received.
Instead of persistent connections, developers should use the PushKit
framework—APIs that allows an app to receive pushes (notifications
when data is available) from a remote server. Whenever a push is
received, the app is called to action. For example, a VoIP app could
display an alert when a call is received, and provide an option to
accept or reject the call. It could even begin taking precursory steps
to initiate the call, in the event the user decides to accept.

What is the best way to handle silent push notifications in iOS

We need to calculate some numbers and display the calculations in local notification on receiving a silent push message from the server.
This works when the app is active/open in background.
This does not work if the app is killed/not in background.
So is there anyway to perform tasks when app is closed and the silent push arrives?
FYI I have enabled background fetch.
Apple's Documentation states:
Note: The ability of APNs to deliver remote notifications to a nonrunning
app requires the app to have been launched at least once.
On an iOS device, if a user force-quits your app using the app
multitasking UI, the app does not receive remote notifications until
the user relaunches it.
The second sentence pertains directly to your question; likely not the answer you hoped for...
↳ Configuring Remote Notification Support

iOS - i need processing time after silent push

My app makes use of push notifications to alert the user when they receive a message. Due to the nature of my server and also due to encryption, the server does not know what the message is, only the iPhone is able to decrypt it. However, i would like the message to show in the notification. So i need processing time after a silent push to download and decrypt the message then use a local notification to tell the user
However, iOS doesn't allow processing time for killed apps, only for foreground ones or ones still in the app switcher. How can i workaround this issue?
One solution i have found is PushKit. This seems to relaunch apps even if they've been force quit. However, it only does this for VoIP apps, my app is not a VoIP app and I think App Review will reject it if I use PushKit
It is exactly as you described it and there is nothing to add. If the app is killed, you have no way of processing a silent push notification other than PushKit, but if you use PushKit, your app won't go through the review if it doesn't implement VoIP.
Your best option is to send push notification with a generic text (e.g. "You have a new message") instead of a silent push notification, that will serve as a fallback for the case that the app was killed. If the app was not killed, you can discard/remove the remote notification, download and decrypt the message and show a local notification with the actual message. If the app was killed, the remote notification with the generic text will be shown instead and the user will at least be notified that there is a new message.
Add this behavior to the FAQ of your app to encourage users to not kill the app. There is no reason to do this on iOS anyways, so if a user kills an app, he shouldn't expect that it works as desired.
Addition on misusing PushKit for this:
If you misuse a functionality/service for something it is not intended to be used for, your app will probably be rejected. So if you enable VoIP background mode, but your app doesn't provide any VoIP functionality, it is pretty obvious.
From the App Store Review Guidelines:
2.16 Multitasking Apps may only use background services for their intended purposes: VoIP, audio playback, location, task completion,
local notifications, etc.

Resources