Suspend sockets connection on applicationWillResignActive or applicationDidEnterBackground? - ios

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.

Related

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.

How to check whether force quit has disabled notifications

I am working on an app that, among other things, provides alarms in emergencies. Users can toggle a setting to have alarms be put through even if their iPhone is muted, but this service has another hurdle to leap: when the app has been force quit, it cannot receive (content-available) notifications until the app is relaunched by the user.
There is a geofencing event in place which buys me some processing time even if the app has been force quit, and in that time, I would like to check if such a block is in place, and if so, request the user to open their app again, and not aggressively force-quit in the future. (Many people still think it's just a way to keep things clean, even though it actually costs you battery life to not just leave apps in the background)
SO THE CORE OF THE PROBLEM: I need an (API call? Something else?) that will tell me whether the app is in such a 'force quit, cannot receive notifications' state, assuming that I do have processing time to do this check.
Anything is welcome, I have not been able to find proper Apple documentation on the notifications block.
Thank you very much.
While there is no API I am aware of to find state after, you can infer the state just before the application is terminated, and record that.
Code
applicationDidEnterBackground
will be called when an app has received a terminate signal.
More Info
This question describes what lifecycle functions to use, and

App running in the background for 3 minutes

I have an app which maintains a socket connection with a server. When the application is backgrounded (Home button is tapped) this connection breaks, and when the user comes back reconnection takes around 5 seconds. Not too much, but still an annoyance.
This works perfectly, but I think I could improve the user experience if the app asked for background execution time with:
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
I get 3 minutes additional runtime here, and the socket can stay alive a little more. If the user returns in these 3 minutes then the there is no reconnection, the app can immediately be used again. (This happens quite often, because they just check their e-mail really fast, reply to a message etc... and immediately return to my app.)
This would definitely improve the user experience, and as I see some apps use this (like the IRC iOS client). The documentation clearly says though:
You should not use this method simply to keep your app running after it moves to the background.
I don't want to run longer than 3 minutes or fake to be a VoIP or Music player app. This would just be a minor user experience improvement. Can Apple reject an app because of this?
(For now let's ignore that the socket connection doesn't break immediately when the app is backgrounded.)
If appstore review team will find it, they will reject the binary. You have definite quote from documentation why you can't use it. Also, if you add background mode like your app is VoIP or Music player, but app is not such kind of application, it also can be rejected.

How to handle a TCP connection in background? for Poker app server-client app

I am working on Poker app based on server-client based app. When Poker App goes to the background after some time TCP/IP connection lost because app unable to send/recieve any packet to/from the server. Sever ends socket connection. how can i able to establish connection for long time and update my game UI
The topic you asked for, is called "Background Execution".
First:
You can't update the UI while the app enters the background. But you will be able to finish your API-Requests to the server and save the data on phone while using beginBackgroundTaskWithExpirationHandler. You can use this method to write a block which communicates to your server and handles all the data your app will receive. If the App enters the foreground again, you can use this data received in background to update your UI then.
It is important, that those background tasks have to finish in a short time, so it will be not a good idea here to have an infinite loop. Otherwise, iOS will terminate your process. How much time you really get after your app gets backgrounded is determined by iOS.
Second:
If you want to keep tcp/ip-connections always on even if the app remains in the background, Apple provides a very powerful background mode which enables you to run code for any time in the background. It's called VoIP-Services. Unfortunately your app should provide some VoIP-Stuff to not being rejected by Apple. Here is a good article about those services.

Keeping iOS socket alive in background mode without VOIP

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.

Resources