Maybe someone ever solve the problem with stable connection to server when application is in background? I need to transfer audio data from server to client app.
I know about all hacks for iOS how to keep alive application, but I need legal methods to solve this problem. Maybe you have any idea?
I found that I can send VoIP push to device that will wakeup my app and then establish tcp connect to my server but this socket will be keep alive about 30 seconds (as I see in log, every 3 seconds fires timer in iOS app that send data to server) this is not enough for me.
Maybe this project https://github.com/SmallSharpToolsOpenSource/Speakerbox will be helpful for someone.
And this video https://www.youtube.com/watch?v=lXJ1LDjL4Os
And official answer from Apple tech support:
PushKit is how voip apps can
reliable receive silent notifications, while CallKit is basically a UI
framework voip apps can use to notify the user about calls. Note that there
is NOT any direct connection within the APIs- for example, a voip app can
generate a local notification (instead of using CallKit) or simply do nothing
and “ignore” the notification entirely. Similarly, a voip app could “fake” a
call at anytime by simply telling CallKit that there was an incoming call (our
sample code for CallKit did exactly this).
Anything your app could previously have done when
it received voip socket traffic, it could also do when it received a PushKit
notification.
Standard voip apps
actually operate in two COMPETELY unrelated “modes”:
1) While waiting for an incoming call, the app is suspended until “something”
(PushKit OR a voip socket) wakes the app to tell it about the call.
2) Once a call has started, the app has an active audio session and is relying
an the standard “background audio” behavior of iOS, just like a wide variety
of other audio apps (for example, any streaming music app).
Related
I have set up the latest linphone iOS code (version 3.16.6) and I am able to make audio and video calls but if my app is in background or killed, not getting calls.
Please guide me in details that what I have to do to get the calls even when app is in background or killed.
Please let me know if there is server interaction part also there.
You have to wake up your application with voip-notification, before receiving call on background.
So you can implement your solution which send notification before every call. Notification wake an app and app receive the call
You can use callkit for UI, but callkit itself doesn't handle any background or voip work.
Use some working solution for example FlexiSip from Belledonne
http://www.linphone.org/technical-corner/flexisip/overview
FlexiSip have builtin support for iOS push notification, but you will need to generate certificates and do some server work :)
EDIT
Voip notification process.
Before every SIP Invite you have send voip notification to target device. Voip notification wake application which will be ready for accepting SIP call.
I'm not sure if you use proxy or if you making just direct calls. If you are using proxy you can try FlexiSIP which should handle this logic for you (I didn't tried). Of course you will need to provide your voip certificates to it.
If you making direct calls without SIP proxy, source application should call same API of some web service which send voip notification for target device (For example Houston API). And after you can send SIP invite from source to target application.
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.
I am trying to implement an iOS chat application using Pusher or PubNub (websockets).
Question: How does message delivery work when the iOS app is in the background?
I understand that Websockets implementations provide real-time messaging and don't cache the messages. Is the message lost because the socket connection is broken when the app is in the background?
If yes, how do I recover the lost messages? One idea is to implement a state refresh protocol every time the app comes to foreground.
PubNub Missed Message Recovery Options
You mentioned PubNub (the company I work for) and as #FrankG mentioned, unless you have permission from Apple to run your app in background (staying connected to internet, and therefore, PubNub), you will not receive any message in realtime.
You can use PubNub's Mobile Push Gateway and receive APNS push messages while you app is in background (but idle/not running) or completely not running (kill state).
When the app is activated again, PubNub can be configured to automatically retrieve missed messages from the channel(s) it was subscribed to, but this is good for short periods of disconnection.
For longer periods being offline, you can enable Storage & Playback and use the historyForChannel API to fetch all the missed messages of all channels you require.
Answer: It doesn't.
If the iOS app is in the background, you are out of luck. There is no official (and Apple sanctioned) way of keeping a connection open when the app is in the background. There are hacks like playing a silent audio track to keep it in the foreground, but Apple doesn't approve of such hacks. You'll need to use APNS to send an offline message to bring the app to the foreground so it can reconnect.
And you are 100% correct that the WS standard does not address caching. That has to be performed by another subsystem in your architecture.
The Kaazing Gateway (disclosure: the company I work for) has a feature in our messaging Gateway that caches the last value sent. When the client reconnects (our client libs auto-reconnect), they will see that value.
I want to sync my local DB with server when Push notification came, but I am not able to do it with Silent Notification because application:didReceiveRemoteNotification:fetchCompletionHandler not called when app killed by user. So, I did not know how to do it, then I read about push kit but don't know is it possible to use push kit without VoiP feature. Please tell me is it possible or not??
If not, suggest me any other idea , how will I run background task when app killed by user??
In my experience as well as others on SO - you get rejected for trying to leverage VOIP as a workaround. See below for actual response from apple dealing with a similar attempt.
2.16: Multitasking apps may only use background services for their intended purposes: VoIP, audio playback, location, task completion, local notifications, etc.
2.16 We found that your app uses a background mode but does not include functionality that requires that mode to run persistently. This behavior is not in compliance with the App Store Review Guidelines.
We noticed your app declares support for VoIP in the UIBackgroundModes key in your Info.plist but does not provide any Voice over IP services.
We recognize that VoIP can provide "keep alive" functionality that many app features would like to use. However, using VoIP in this manner is not the intended purpose of VoIP, which, as indicated in the iOS Application Programming Guide, is that: "A Voice over Internet Protocol (VoIP) application allows the user to make phone calls using an Internet connection instead of the device's cellular service."
Seems that the only way to restart the app when it was killed by user is to use PushKit.
It is possible to use PK framework in your app without Voip functionality, but I can't guarantee you, that your app will not be banned while posting to AppStore.
I'm trying to place OpenTok video calls within an iOS app but am stuck on a good mechanism for notifying users of an incoming call in real time (within a few seconds). Are push notifications my only feasible option or is there some other way? Would like to avoid this since APNS makes no guarantee of notification delivery.
I suppose I could create some server scripts that poll every few seconds, but it seems like there must be a better solution.
As a VoIP app, this app is allowed to register a socket that the OS will monitor for you, and wake you when there is traffic on it. Your app will connect to your server and perform a long-poll. When there is a call, your server will send data to the client on the connection, and if your app is suspended, iOS will awaken it to deal with the incoming data.
VoIP apps are allowed to set a keep-alive timeout, so that you can periodically reconnect to your server, and are automatically launched on boot to service incoming calls.
See "Implementing a VoIP App" and "Tips for Developing a VoIP App" in the iOS App Programming Guide.