Keeping iOS socket alive in background mode without VOIP - ios

We have an game that creates a player lobby using sockets. When the player creates a lobby, a game is created on our server. Unfortunately if the user switches our app away with the Apple button, another user may join the game and the game will start with just one player active. So we want to send a message to our server via a socket when the app transitions to the background to close the lobby, stopping others joining.
But we can't. The sockets get frozen on entering background mode. Even if we keep the app alive a while using beginBackgroundTaskWithExpirationHandler, no socket activity works.
VOIP is not an option, as the title is not VOIP related and will get bounced immediately from Apple submission.
Any one got any non-VOIP related ideas?
Many thanks,
Steve.

I think what you want to do is to let the server know that this user is off-line when touching the Apple Home button.
I am using GCDAsyncSocket, but other ways may be similar.
What I'm doing is
Add observer on UIApplicationDidEnterBackgroundNotification.
When application enter background then call socket disconnect. The server will know that you are off-line.
I know this is a little late for your answer, but could be helpful for others.

Related

Persistent connection when iOS app is in the background/terminated?

I'm new to Swift and iOS app development, and my boss wants me to fix the iOS app. The user has an option to start listening for events from someplace (using alamofire's AF.streamRequest), and then when it receives a response from that place he wants the app to create a new api request and send that out (based on the response).
The way the code is implemented, the app stops listening as soon as it goes into the background or is terminated. Sometimes when the user comes back into the app - after it was in the background but not terminated - the app will receive the missing events, other times it errors out and the stream request stops entirely.
Is there a way to make a persistent connection work on an ios app even when the app is in the background or terminated?
Any help would be appreciated.
Thank you.
If the app is terminated by user there is no way to wake up your app again.
Running your app in background is only possible for some specific tasks like play music, ...
Take a look at the documentation: Handle Background Events

In Backgrond WebRTC offer is not working in iOS

In WebRTC i m giving offer when the app is open and working fine and when it goes to background or Phone is unlock offer is not going.How offer can be sent.Can any one help me.
You have several ways to implement this
1) declare your application as VOIP. This kind of application is allowed to have one signalling socket working even in background mode; you should use setKeepAliveTimeout:handler: method as well in order to keep your socket connection active. As soon as new data will be ready for reading on this socket your application will be awaken and you can send local notification to let user know about incoming call. But this approach is deprecated and isn't battery friendly.
2) Simple way is you can just make use of voip push notifications.

Handling server being aware if iPhone app is running (heartbeat)

I am not sure how to best implement keeping our server informed that our iPhone application is currently running (even when in the background). There are a few different options but there is some concern as to what is allowed by the Apple approval process as well as what is the most reliable. The application does have the ability to play music in the background, if that factors into what is approved by Apple.
The first option, is to continually send some sort of heartbeat to the server at a set interval through a simple GET/POST; however, the concern is whether or not this is allowed as a background task. In a very roundabout way it can be argued that it is necessary for the playback but I'm not so sure whether or not that is acceptable. If the server does not hear from them in a set amount of time it will assume the app is no longer running.
The second option involves using a presence channel socket connection and have the server just handle when users enter and leave that channel. With this option the main concern is how reliable is a socket connection like this while an app is in the background. Similarly, whether or not this is allowed by Apple. In this case when the app dies, connection closes and server knows app is not running.
Third option can be used in tandem with either of the other options but to use some sort of APNS push to query the phone as to whether or not it has died and have it respond with some data to let us know; however, this seems somewhat counterintuitive as the push itself wakes the app up.
Any other suggestions or input are also welcome.
Not sure if this should be a comment or answer, but let me put my 2 cents here.
Firstly, Can you please elaborate your needs further, because in case you are playing an Audio in background with AVPlayer/AVPlayerItem you would hand over your content URL to iOS and it will make the calls as and when necessary to keep the playback running, you dont need to know about apps' state.
Let me assume, for whatever reasons you want to achieve what the question asks:
There are 3 states your app can be in when it is "Not Running"
i. Suspended State: your app is not killed but its not receiving any CPU time to execute your code.
ii. Killed by OS: Your app can be terminated by iOS to free up the memory or any other resources.
iii. Force Killed by User: If user swipes up your app from app switcher it gets force killed.
Now when your app is Not Running, you CAN NOT query it, but you can move it to Running State. You can achieve this transition by using following methods (Not exhaustive list, but mentions common ways)
i. Background Fetch : You can configure your app to be invoked periodically, so that it can synchronise with the server and updates its state.
ii. Push Notifications (APNS) : You can ping the app from server so that iOS invokes it for some short period of time (few seconds) to update its state.
iii. VOIP Pushes: If your App is VOIP app you can use PushKit to send Silent Pushes which will launch even the Force-Killed Apps, the above two methods does not transition the app to Running state if it was force killed by user
The above point can be helpful in devising overall strategy but does not answer the question, "How to keep syncing the RUNNING state"
i. When your app is Running(Forground/Background), you can do almost anything that is publicly documented, you can keep calling a URL every minute or every 5 seconds, you need to worry about UX on the device rather than approval process, (People will delete app if they see your app in top battery drainers in the settings section)
ii. For making an HTTP call while your app is in background, you can look at Background URL Session, which off loads the HTTP calls to another process so that the call completes even if app gets killed.
iii. For the socket based approach please refer this technical note. The main issue is that you do not/can not know when your app moves from Running to Not Running State.
iv. As you mentioned that your app uses background audio, it will be always be in Running state if the user plays an audio and puts app in background, in such case you can use Periodic Observer to do some Heartbeat call periodically when the content is being played out.

ios 8 periodic background process even after app termination

NOTE: This app I am working on is completely for my own usage and will not be on app store so please don't give answers referring that.
I want my app to do some process in background or after termination (double tap the home button and swipe the app from applications multitask) every few minutes. The process is very very light and quick so it won't drain the battery. This process shouldn't require internet connection. I have seen some answers here like and I will explain what are the problems:
VoIP. The problem with VoIP is wither it should be in background to use UIApplication.sharedApplication().setKeepAliveTimeout(..) method which doesn't work when the app is terminated or it should be connected to the internet to establish tcp connection and receive commands from sever and as mentioned before I want it to be internet independent.
Location Services. I found this excellent site with some great articles but the problem is it only works when the mobile phone is moved more than 500 meters. It depends on the location movement so when the phone is staying somewhere there will be no code execution.
Playing an silent audio loop. The problem here is if the user plays another audio (which is completely possible like music or phone call) the app will terminate!
Jailbreak Launch Daemons. I can't require jailbreak so it should be solved with a non-jailbreak solution:(.
I am free to use any kind of private-API's and there will be no restriction for that.
Thanks in advanced
I also faced with such problem, and don't find any solution.
The main problem is if user manually terminated app - in this case you can't do nothing...
Only way is:
a) use Location Services (as you mention)
b) use Push Notifications with background fetch

Suspend sockets connection on applicationWillResignActive or applicationDidEnterBackground?

I'm wondering which is the right delegate to suspend the sockets connection to resume it later and why.
From what I've read and seen in other projects that used sockets, applicationWillResignActive seems to be the right one, but I've also noticed that it's being called quite too often. (Even when showing the "Itunes InApp" purchase dialog)
I wouldn't like to close connection when it's unnecessary. As far as I'm concerned, on Active state, the application is still able to handle sockets so there shouldn't be a problem if I close connection when app enters background instead, but I wouldn't like app to just go to background without making sure connection is properly closed and miss messages on the process.
Same happens when resuming connection. As of now it's on the applicationDidBecomeActive delegate but maybe it makes more sense to be on applicationWillEnterForeground.
Are there any reasons to use this delegate?
Thanks!
So, seeing as nobody is answering I feel I should add some response from what I have discovered based on further testing so this questions is not left unanswered.
Basically it makes more sense to suspend/close connection when app goes background and resume/reconnect when app enters foreground.
The reasoning behind this is that applicationWillResignActive will happen too often and even when the socket connection can still kept open. When receiving any alert, a call or activating the multitask, but the app is still alive and fully operational.
This also means that, if you work with in-app purchases, when you are prompted to enter your iTunes details, connection will be close, this can be a problem if you are also managing those purchases with your own backend and need the connection alive.
From what I've seen, when the app enters background is when socket connection cannot be kept alive anymore and should be safe to just close it on applicationDidEnterBackground instead.
As a side note, remember to make sure connection is properly closed as you only have approximately 5 seconds to do whatever you need here, specially if you are listening to a socket close event to do some stuff.
Again, this is from my experience. If you have more information on this matter feel free to let me know.

Resources