when iOS removes an app from memory - ios

This question might have been asked before but i couldn't find an answer. If i open an app and press home button it goes in background and if i open it again it calls app delegate methods such as "applicationWillEnterForeground". How long it will take me to be in background so app calls didFinishLaunchingWithOptions and starts the fresh app?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Thanks

There are many factors that are taken under consideration to remove your app from the memory (kill the process).
The most simple one is rebooting the device. All apps are off after a reboot. Apps with Voip however are launched automatically into the background after a reboot.
The second and most common one is memory pressure. If your app is in the background and system runs out of RAM, it kills the suspended apps starting from the one that consumes the most RAM and keeps killing them until it reclaims enough memory.
Another, quite common one is something known as the watchdog. There are specific scenarios when your app's main thread has a limited time to finish the task. For example, when you app returns from the background or when the user presses the home button, you have about 10s to free the main thread. (Keep in mind there are situations such as background tasks, music playback and other, that grant your app more execution time in the background).
But, a typical app will be killed if the runloop does not return in about 10.
Another case worth mentioning is if your app uses very little RAM. It was mentioned in one of WWDC sessions, that if your application consumes no more than 16MB of RAM, it will be dumped to flash storage, and restored back to the memory on reopening, rather than being killed. So in this case your app may never be killed (I'm not sure about the reboot, but I assume the dumped image is ignored after a reboot and a normal launch process happens).
Next one is the user's explicit action, that is entering the multitasking UI and swiping the app upwards, which will kill the application.
I think that sums up the most common scenarios.
And of course you might also want to have a look at the docs: https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html#//apple_ref/doc/uid/TP40007072-CH2-SW1

How much RAM does the device have? Have much RAM was your app using? Are you following best practices when your app receives didReceiveMemoryWarning:? Are you opening other apps before going back to yours? This is such a "it depends" question.
What's the larger question here? Why do you want to know when your app will get purged from memory?

Related

What's the difference between cold launch, warm launch?

Are these some made up terms? Does cold mean app was killed. And warm means app was in memory?
From docs on Reducing Your App’s Launch Time
For example, on iOS, if you swipe back to the home screen and immediately re-enter the app, that is the fastest activation possible. It’s also likely to be a resume. When the system requires a launch is required, it is commonly referred to as a “warm launch.”
Conversely, if a user just played a memory-intensive game, and they then re-enter your app, for example, it may be significantly slower than your average activation. On iOS, your app typically was evicted from memory to allow the foreground application more memory. Frameworks and daemons that your app depends on to launch might also require re-launching and paging in from disk. This scenario, or a launch immediately after boot, is often referred to as a “cold launch.”
Think of warm and cold launches as a spectrum. In real use, your users will experience a range of performance based on the state of the device. This spectrum is why testing in a variety of conditions is essential to predicting your real world performance.
From WWDC:
So, let's take a look at those launches I talked about before, there's a cold launch, a warm launch, and something is often referred to as launch, but isn't quite a launch, a resume.
Cold launches occur after reboot, or when your app has not been launched for very long time.
In order to launcher app, we need to bring it from disk into memory, startup system-side services that support your app, and then spawn your process.
As you'd expect, this can take a little time, but fortunately, once it's happened once, you'll experience a warm launch. In this case, your app still needs to be spawned, but we've already brought your app into memory and started up some of those system-side services. So, this will be a little bit faster and a little bit more consistent.
Finally, there's that resume. This occurs when a user reenters your app from either the home screen or the app switcher. As you know, the app is already launched at this point, so it's going to be very fast.
What you need to remember from this is not to confuse resumes with launches when you're taking measurements
tldr:
every time you hit the app icon, it can be one of the 4 following states:
app wasn't launched for a long long time or it was just launched after a reboot
app was launched and killed before. But launched again. So some system services are still in memory.
app was launched before, but got suspended to reduce memory, it's process is still ongoing. Hitting the app icon won't trigger an app launch
app was launched, but then only backgrounded. It's still in memory. e.g. you've had app put in background while listening to music or location tracking. So tapping on the app on the app icon, won't trigger another app launch. (this scenario wasn't mentioned in the above docs, but was worth mentioning)

iOS Background Mode: After running location updates in the background, the app never terminates

I'm running location updates in the background. All works well:
On significant location the app is launched in the background
- appDidFinishLaunching(options:) is called as expected.
I start LocationManager startUpdatingLocation() and startMonitoringSignificantLocationChanges()
Locations are collected correctly.
After some time, I call stopUpdatingLocation()
My program at this stage doesn't need to do anything and no further code is executed
At this point the program stays idle. applicationWillTerminate is never called again. Is this expected? I'd hoped the app will shut down again as no location updates are required.
What's the expected behaviour? Should the app shut down or should it stay idle forever?
Once this happens, then if a user user opens the app or a significant location is received again, then appDidFinishLaunching(options:) is NOT called, but instead applicationDidBecomeActive.
Is there any documentation I can follow that supports the expected behaviour?
Yes, everything here is expected. There's a deleted answer from J.D. Wooder that correctly linked the documentation: "Managing Your App's Life Cycle." As a rule, background iOS apps are not proactively killed. They are only killed when system resources are needed. This is unpredictable, and the app typically will not receive a applicationWillTerminate message when it happens (because the app typically is not running at that point, and it won't be woken up just to kill it). Your app should handled both a cold launch (appDidFinishLaunching) and a warm launch (applicationDidBecomeActive).
Restarting an app from scratch is expensive, so iOS prefers to keep recently used thing in memory if there's no resource pressure. Apps that are doing nothing are very cheap. to keep around.
Note that iOS 13 has grown much more aggressive in killing apps in the background, and that the large cameras on new phones are leading to memory pressures that kill apps more quickly as well, so don't get too comfortable with running in the background for a long time. But it's also very normal.
Please see the iOS app Life Cycle,
appDidFinishLaunching will call only when app Launch,
applicationWillTerminate - called when app terminate from background
applicationDidBecomeActive - Called when app comes to foreground from background

How to make an iOS app not be killed by iOS system in background?

Subtitle: How to make an iOS app launch so fast from background to foreground state?
I just reviewed the App Life Cycle page and make some conclusions.
Checked out the excellent apps like Apple Reminders and Spark mail, their app's launch screen just occurs in the first launch time mostly, after that, no matter how soon it's launched, the main screen will show quickly in my iPhone 6 device. (1G RAM, with lots of app installed.)
Here is my guess, the main cause is on data management when receiving memory warnings, it just releases all the retained data (array) of view controllers and other reusable objects. The app keep a low-level memory usage all the time, especially in the background state, when iOS system get the low-level usable memory to run the active app, it sends the memory warnings to all the un-active apps, especially for the background apps, if someone keeps a high-level memory usage after receiving memory warnings, iOS will try to kill it absolutely, or it's allowed for background apps to keep a low-level memory usage.
If so, how many/percent used memory for iOS app is allowed? What's the threshold? Any documents for that?
I did a lot of search with no luck, please point it for me, great thanks!

Is there a way to know when my app switches from Suspended to another state?

I'm having issues with my WKWebViews'cache being purged sometimes when a user hasn't been using my app for a while.
I guess, that's because iOS puts my app in Suspended and then a low-memory condition occurs so my app is purged.
I read Apple's documentation about The App Life Cycle - Execution States for Apps
Especially the part describing the Suspended state :
Suspended - The app is in the background but is not executing code. The system
moves apps to this state automatically and does not notify them before
doing so. While suspended, an app remains in memory but does not
execute any code. When a low-memory condition occurs, the system may
purge suspended apps without notice to make more space for the
foreground app.
Two questions here :
1) What does "purge" mean exactly ? The app is killed ? Or does it still appear on the app selector ( when double-tapping the home button )
2) Here we can see that there is no way to know when an app is going to be suspended. All right. But if a user comes back to the app, is there a way to know, then, that the app has been suspended ? I can't find any UIAppDelegate's method to do so, but there might be another solution ?
Purge - The purge command forces disk and memory caches to be emptied,
offering a ‘cold disk buffer cache’ which is similar to the state of
the operating system after a reboot.
Referenced from here
As per the documentation
applicationDidEnterBackground:—Lets you know that your app is now
running in the background and may be suspended at any time.
This is the only method which will let you know that method may will enter in Suspended State
also
application:didFinishLaunchingWithOptions: will let you now that
your app's launch process is almost done and the app is almost ready
to run.
The app is in the background but is not executing code
I think it's explained good by Apple, the app is still in memory but no background threads are executed since foreground app requires more resources. Maybe when memory is restored, your app can execute background code again if has not been killed by OS.
When low-memory condition occurs, you're app could be killed (purge).
Is there a way to know, then, that the app has been suspended?
When app is killed from OS, next launch is equal to a complete new restart of app. For this AppDelegate doesn't provide a method to achieve this. You could set a flag in UserDefaults when app goes in background and then make some logic on that flag.

Non-persistent data when app goes background

Is there a any chance that an in memory data might be lost when an iOS app goes to background?
for example if the OS give notice to the app with
didReceiveMemoryWarning and the app didn't take any action to release some space.
so far I have never notice this.
Not instantly, but the app may be terminated at any point, if other apps are used and the system decides, that it needs the memory blocked by your app.

Resources