How do "Suspended" and "Not Running" states look like for the user? - ios

I'm trying to work out the lifecycle of an application, but I can't imagine what some of the states look like.
The program goes into a suspended state when there is no code to run in the background, right? It's still in the background (memory) but can't do anything. Now the question arises, how does it look to the average user? It can still be seen in the app switcher, but will the app restart if I want to open it?
But what happens if that app runs out of memory and goes into the "Not Running" state? Is it still visible in the App Switcher, but will the app restart if I try to open it again? What is the difference in Suspended and Not running state to a user?
Could you help me with this question?
Documentation: https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle

They don't look different to the user at the time. The app is listed in the app switcher regardless of whether it is suspended or not running. The app switcher makes no distinction between "it is suspended" and "it is not running but it was running recently".
However, if the user taps the app in the app switcher, what happens next is different. If the app was suspended, it simply resumes right where it was when it was suspended. But if the app is not running, it launches from a cold start, the same as if the user had killed the app and then tapped its icon in the springboard.
For some apps, this difference is quite noticeable. Apple's Books app is a good example; if it resumes from suspension, the user is instantly still reading the same page of the same book, but if it launches from a cold start, it does an involved dance that takes quite a long time, passing thru the library and visibly opening that book, to eventually get the user back to the same book and the same page.
Apple has said that ideally you should write your app in such a way that both situations look identical to the user, by saving state when you go into the background so that you can quickly restore that state the next time the app is cold-launched; but as I've just demonstrated, Apple itself does not always meet that goal.
Another goal is to try to prevent the app from being killed while suspended in the first place. You can't prevent the user from killing the app from the app switcher, but you can try at least to discourage the system from killing the app while suspended. You can't guarantee this but you can try, by not using very much memory for instance, to fly under the radar so that the system will let your app live when it is looking for apps to kill in order to free up resources. Apple has an interesting video on this topic (which would have answered your question), https://developer.apple.com/videos/play/wwdc2020/10078/.

Related

App terminates after about 5 mins after the pressing lock button

While my app is in the foreground if a user presses the lock button the app will resign from activity but should still be ready to start again when the user unlocks their phone. After about 5 mins or so my application ends up being terminated and when they unlock their phone they are back on the home screen. Is this expected behaviour? As far as I know I havn't experienced this situation until I started a new project. Am I doing something wrong here or forgetting some sort of setting?
The Operating System can terminate your application at any time to free resources for other processes that may need them or to conserve battery life.
"Apps must be prepared for termination to happen at any time and should not wait to save user data or perform other critical tasks. System-initiated termination is a normal part of an app’s life cycle. The system usually terminates apps so that it can reclaim memory and make room for other apps being launched by the user, but the system may also terminate apps that are misbehaving or not responding to events in a timely manner."
(Source: Apple Developer - "The App Life Cycle")
To minimize the likelihood of this happening to your application, look at what processes are running and do what you can to stop/ pause them while the application is not in the foreground.
Regardless how quickly this happens, it's important to design your application to handle the situation where it may be terminated in the background as this is something that can and will happen. Save state and critical information, such that on next launch the user can continue where he left off.

iOS Memory App Closure

When putting my app in the background, then running a bunch of other apps one after the other, it will eventually close my app due to phone memory management. This is understandable. My question is, can anything be done to notify the user A) The app closed because of memory and needs to be booted back up. OR B) Have some sort memory watcher to when the phone memory is getting low to alert the user?
Are either of these possible? Are any other options available?
This is understandable
Understandable but not necessary in the short term. You cannot prevent your app from eventually being terminated, but you should be doing everything you can to keep it off the "short list" of apps to be terminated when memory is needed, by shedding memory usage as you go into the background.
can anything be done to notify the user A) The app closed because of memory and needs to be booted back up
No. You cannot "notify the user" when your app has been backgrounded and suspended, because it has been suspended — it isn't running. You can't do anything at all. No code is actually being executed. You are like a frozen corpse. Unlike the corpse, you can be revived and brought back to life, but that is entirely up the user, who must summon you to the front again.
Your job in this respect is to make it, as much as possible, not matter whether or not the app was terminated while in suspension. If you were not terminated, you'll be revived in exactly the state you were in when you went into the background. Well, then see to it that if you are launched from scratch because you were terminated, you also return to the state you were in when you went into the background.

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.

Is there a way to prevent iOS6 to kill the specific task process?

I know that iOS has its own task management method and users may never need to care about the processes background. But my requirement is to ALWAYS keep a program alive, it cannot be killed under any circumstance.
Is there a way to do this like "LOCK" or something else function already existed? I'm using iPad4 ios6.01 system.
Thanks
No, that's not possible. (Nor should it be if you think about it. What's to stop every app from saying that it can't be killed?)
The closest you can get is for things like VoIP apps that do run in the background and automatically respawn when they die.
The alternative is to work like every other app: when your app goes into the background you save state so you can restore if it gets killed. iOS 6 even has the state restoration functions.
Short and simple
No, there is no way to make your App "unkillable".
A bit longer
If your App requires to receive location updates while it is running in background, you can use the standard way Apple offers to do so.
Two other options are: your App is an VoIP application (afaik they also get autostarted on system boot) or you're playing audio in the background. Without knowing too much details about how iOS handles such Apps, they might get killed if the iDevice runs out of memory (or the user kills it). But you probably already knew that.
However, as you already mentioned, iOS manages everything on it's own and will kill Apps that run in background to free memory. Additionally as we all know, a user might kill your App at any time using the task switcher of iOS.
And don't try to use the described methods just to run tasks in the background. If Apple finds out about it, your App will be rejected/removed from the App Store quickly.

Sending Application to background on iphone

Is it possible to send the application to background programmatically on iPhone?
Under iOS 4.0, your app will be put in the background if another app enters the foreground, and there are enough resources to keep your app in the background. You could send a URL to Safari, or another app that has registered for a handler, and hope that there's enough memory (etc.) that the OS puts your app in the background after it starts Safari (or whatever app handled the URL). If you are lucky (which typically happens fairly often), you will have sent your app programmatically to the background.
Of course, whether your app runs in the background, or is just suspended, depends on other things (which you have to register with iOS 4.x for).
Apple does allow apps to exit (kill themselves) programmatically. But it's meant only as a last resort for when something bad happens from which your app cannot recover.
On all other occasions, apps are expected to stay in the foreground and running until either the user presses the home button or the app opens another app, with the users consent.
Actually you don't want to kill the app, however moving it to the background and returning to the home screen would leave a very similar impression. That's why I don't think Apple would approve it and consequently doesn't offer, as far as I know, any means to move an app to the background programmatically without opening another app.
No it is not possible. Only iOS can put your application in the background.
Note that there's a lot of confusion between "background" and "inactive". An inactive application is one that is not displayed on the GUI but is still running.
Technically an application in the background isn't running; it's dormant. Depending on the mode used, a background applications can receive signals and "wake up." See Background Modes for more details: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW22
But a background application can also get terminated at any point without warning. As a matter of fact I always treat a background application as terminated. Therefore you should always clean up your application before you enter the background, and re-initialize it when you enter the foreground.
This is a must-read on this topic: https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html
check out these post
local notifications?
iPhone - Backgrounding to poll for events

Resources