Is there any way to notify my video chat application that there is an incoming video call when the app is in the terminated state? (Like an Android background service.)
I notify of incoming calls via socket when the application is in the running and background states.
App that are using VoIP are treated differently by apple and have more privilieges. In the past, that meant keeping a permanent connection to the server to get notified when a call occurs.
This was not very efficient in terms of energy saving.
Since iOS8 it is recommanded to use PushKit (the push notification API) to notify your user when a call occurs. Apps with VoIP privileges will be notified on the spot and that can wake up your app whatever the state it's in.
Here are the world from apple :
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.
https://developer.apple.com/library/ios/documentation/Performance/Conceptual/EnergyGuide-iOS/OptimizeVoIP.html
Get pushkit payload
Implement pushkit at ios code side
Once you receive silent notification
Schedule local notification
Keep important information in local notification's userinfo
Also keep local notification object in NSUserDefault
If your device gets restart then you can retrieve localnotification userinfo from NSUserDefault object
Once you get silent notification your socket will get active upto your local notification sound plays ( Max 30 seconds )
If you want incoming call ringing more than 30 seconds then server has to send silent notification at each 30 seconds
Delete previous object and reschedule latest on local notification
Let me know if you need any help in push kit implementation.
Related
While working with APNS, I was able to have push notifications work flawlessly while device is online.
For any APNS push I send while device is offline, only the last one is received once the device is back online. This seems to be coherent with Apple's Store-and-Forward design.
However - I did notice, that when sending WhatsApp messages to an offline device, once this device goes online it receives all push notifications (one for each message). This is not something based on collapse identifier, but rather independent push notification for each message.
So how did WhatsApp do it?
Tried using Notification Extension and attempt to post multiple local notifications, but this also fails as extensions are not allowed to do that.
Instead of a normal push notification, use a Background Notification, which will not show anything visible, but wake up your app in background. Use this event, to make api call, get relevant data and generate multiple local notifications.
Note the following from the documentation when you implement application(_:didReceiveRemoteNotification:fetchCompletionHandler:) :
system calls this method when your app is running in the foreground or background
system does not automatically launch your app if the user has force-quit it
you must call the block in the handler parameter (fetchCompletionHandler) or your app will be terminated. Your app
has up to 30 seconds of wall-clock time to process the notification
and call the specified completion handler block
Apps that use significant amounts of power when processing remote notifications may not always be woken up early to process future
notifications
Please read relevant documentation completely before making ANY assumptions about how you think this should work.
Here's what docs state:
The priority of the notification. Specify one of the following values:
10–Send the push message immediately. Notifications with this priority
must trigger an alert, sound, or badge on the target device. It is an
error to use this priority for a push notification that contains only
the content-available key.
5—Send the push message at a time that takes into account power
considerations for the device. Notifications with this priority might
be grouped and delivered in bursts. They are throttled, and in some
cases are not delivered.
And about VoIP:
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.
Do I understand correctly that apns-priority defines message queuing at APNS side, and VoIP push type defines what happens on the device?
And what do they mean saying
It is an error to use this priority for a push notification that contains only the content-available key.
Will APNS return an error or is it just a bad practice?
P.S. I use AWS SNS for sending notifications and it does not support customisation of apns-priority, but I am curious how it affects the process.
The main difference is that even if your app is closed voip notification can wake your app for kill/suspended state and user notification just shows an alert without waking up your app for more refer.
Apple documentation for pushkit
The main difference is that VoIP notification will launch your app if it's not running or was killed from app switcher and you need to handle the notification in your code, while the normal notification will be shown immediately as local notification and will not start your app.
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.
The first solution I can think of for the incoming call notification is Apple's Push Notification service. However, it is not guaranteed.. there's a relatively high chance it may get lost.. and in a VoIP app, the incoming call notification is so important that I can't afford to miss it too often...
Thus, I followed the tips and enabled the Background Mode to keep the app alive and listening to any incoming call invite. By right, I should just show local notification when the app gets the incoming call invite. This works pretty well when the app is in background/inactive. HOWEVER, when user kills the app manually, no code will get executed, so the app won't get any incoming call invite in such a condition... And because of this particular scenario, I still have to rely on remote push notification.
What I'm trying to achieve is.. waiting for remote notification first, if it arrives, then do not show local notification anymore. If it's lost, then show local notification so that user will always get notified.
The problem is... I have no way to tell if a remote notification has arrived.
I want to know what is the best practice to handle incoming call notifications for a VoIP app?
From appleDoc Apple Developer Docs. (Updated link)
In iOS 8 and later, voice-over-IP (VoIP) apps register for UIRemoteNotificationTypeVoIP push notifications instead of using this method. Using push notifications eliminates the need for a timeout handler to check in with the VoIP service. Instead, when a calls arrives for the user, the VoIP service sends a VoIP push notification to the user’s device. Upon receiving this notification, the device launches or wakes the app as needed so that it can handle the incoming call.
Just play a very long duration audio when a APNS comes.
I have a VoIP app, where the incoming call notification is very important.
The problem is, sometimes I don't get the push notification (even Apple said it's not guaranteed). But, I do have a mechanism to notice that an call is coming while the app is in the background.
So, what I want to do is.. still use Push Notification as the main handler for incoming call (because it handles the situation when app is closed). However, if the push notification failed to deliver and my app gets the call invite, I will raise a local notification, telling user that you have an incoming call.
My question is... how can I check if a notification is showing before I decide whether to fire a local notification?
AFAIK you can only detect the notification when the user taps on the banner OR if the app is open when the notification comes. So I can't see a way to detect if the notification has come yet or not. Just adding to the pain, push notification is famous for its unreliability.
There’s no API to get any information about the state of your notifications. Since you’re making a VoIP app, you have the option to have it get woken up for incoming data, which would let you post your “incoming call” notification whenever you need it—see the “Configuring Sockets for VoIP Usage” section here.