iOS 12 terminates apps in the background for no reason - ios

Starting from iOS 12 the CLLocationManager doesn't run endless anymore in the background. The app get's terminated without a crashlog at random times. This was working fine before iOS 12.
To demonstrate this problem I've created an sample app here
The demo app just launches an CLLocationManager and keep this running in the background. While running on the background we keep track of it by logging it. The problem is that the app get terminated by iOS. The demo app is created to demonstrate this problem.
Steps to reproduce
Run the app on the device
Grand access to locationmanager
Put the app to the background
Wait for 1-48hours
Result:
The app is terminated
App is terminated without any reason after random time.
Expected result:
The app is still running.
How it should work
This is confirmed by an Apple engineer:
Once the CLLocationManager updates are started in the foreground and you did all the work to have it running in the background, the location updates should run endless in the background until:
app is force quit
device is rebooted
app stops location updates
app releases the CLLocationManager object
app crashes
iOS terminates the app due to memory shortage,
the locationManager object is released, overreleased, or overwritten. You should make sure that your view controller is not being instantiated, which then resets the locationController class. If that happens when the app is in the background, you will restart updates, which will cause the app to be eventually suspended. You should make sure the locationController is a singleton.
app is crashing. Check to see if there are crash logs on the device you are testing
iOS is terminating the app due to memory shortage. In this case, you will find JetsamEvent logs on the device that shows your app being terminated. You can check the timestamps and locate the one that is around the time your app stopped working.

Updated answer:
Apple fixed this bug in iOS 12.2 beta 2 (16E5191d)
Original analyse and bug detection:
Together with Apple Developer Technical Support we have analyzed this issue with Sysdiagnose files. Following these guidelines you can install profiles to have more logging on your device. I don't know exactly how these logs work and where to find this issue, but Apple did this for me and came with this first analyse:
On the suspension event you observed on 2018/10/22 01:01:12:587, this
is what I see (about a minute after your last activity logging)
[CllocationManag:2725] Terminating with description:
{
owner = ;
target = rw.sp.flitsmeister.frameworks.CllocationManagerBackgroundTest; }
This is basically saing that your app was terminated, because the
system needed drive space, and killed a bunch of apps so it can delete
their /tmp and /Library/Caches directories. I have seen this process
to be a little more aggressive in iOS 12, but seeing you are on a
256GB device, and have ~179 GB free after the cleanup, I am finding it
hard to believe this was justified.
After sending some more sysdiagnose and reproduction cases Apple did his best to analyse and ended with the following conclusion:
Unfortunately I don’t bring good news.
It turned out that, currently in iOS 12 there is a new mechanism that
will terminate long running background apps periodically as the system
needs to free resources. At this time, this process is a bit too
aggressive, and I am working with the relevant teams to get this to
behave better.
So, at this point, I would like you to file a bug report. Explain the
symptoms. And make sure you upload the sysdiagnose files along with
the bug report. (I already sent yours in, but it doesn’t hurt to have
the new ones as well). And let me know the bug number please.
So this means that currently in iOS 12 you app won't run endless on the background. I've filled in a bug report, the number is 45581276 and will try to keep this thread updated.

I tried clearing out the /tmp and /Library/Caches directories when the app goes in the background without any change in behavior. I also tried the same periodically when the app processing background locations without any change as well.

Related

iOS app getting killed in background - how to debug?

My iOS app gets terminated when put in background. I get the following logs in the device console:
Background Task 160 (""), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
followed by
Background task still not ended after expiration handlers were called: . This app will likely be terminated by the system. Call UIApplication.endBackgroundTask(_:) to avoid this.
and the app terminates and restarts on resuming from background
The new metric kit background exit data (iOS 14) is also reporting that BackgroundTaskAssertionTimeoutExits are killing my app
On breaking on UIApplicationEndBackgroundTaskError, I get the following backtrace:
I have not implemented any background tasks myself but there are some third party libraries integrated in the app that do.
What is the right way to debug this?
If you did not start any background task, and you do not perform anything most likely some of your 3rd party frameworks are causing the crash.
Update to latest version of all your dependencies, to see if the issue was fixed.
If your issue is easily reproducible, try to disable them 1 by 1 to see which is causing the crash.
After that go on the library support page and see if there are any bugs for your issue and if not open a bug.
Start with the usual suspects, Analytics, Loggers and go on.
Have a look also at this thread: App is crashing on only iOS 13 in the background mode

iOS App running on iOS 13 is resetting each time the user goes into background for at least 30sec

It is not really a question but I wanted to write it down here so other people facing the problem could find the solution.
Since the release of iOS 13, some of our users were contacting us telling that our app was resetting each time they go into background for a medium amount of time (approximatively 30sec).
Of course, absolutely no clue of the behavior, nothing on Crashlytics etc. We were able to reproduce on a QA device but unable to reproduce on a debugger attached device.
So obviously we used the Console to monitor what's going on and we noticed that a weird message was being sent after approx. 25sec after our app was put into background:
default 10:14:01.658579+0100 XXX RunningBoardServices Received process assertions expiration warning!
default 10:14:01.659214+0100 XXX RunningBoardServices Notifying client of imminent expiration of assertion
default 10:14:01.659568+0100 XXX RunningBoardServices Expiration notification complete
If you were fast enough to relaunch the app, everything just worked fine, but if you left the app inactive for another 5sec (approx.) and then relaunched it, then the app was resetting (appDidFinishLaunching...).
...
...
We dug deeper and deeper without finding anything... until we decided to update some of our external libraries through Cocoapods, and guess what? we found our guilty guy: GoogleDataTransport from the Firebase suite!
We were using the 1.1.3 version and updating to the 3.0.1 fixed the issue. I guess they were doing some "bad" stuff in the background...
That's it guys. I hope it will help some others!
Cheers.
EDIT:
From this page (Firebase release notes) https://firebase.google.com/support/release-notes/ios#6.11.0, you can read:
Fixed race condition that prevented upload from completing while app was in the background.
Version 6.10.0 - October 8, 2019
From what I understand, maybe Firebase was not notifying iOS that the upload they were doing in the background was completed. It could explain why iOS 13 kills an app in this case.
🤷‍♂️
EDIT 2:
Apple apparently released an iOS update (13.2.2) which is supposed to solve these background issues: https://twitter.com/engadget/status/1192512171252551682?s=12.
Fixes an issue that could cause apps to quit unexpectedly when running in the background
We tested it using an old app which does not include our previous fix and unfortunately the problem is still present...
The crash was due to a background task leak. In my application, some SDKs don't use the background task correctly. Because it was killed by the watchdog, debugging will not appear, you can print beginBackgroundTask and endBackgroundTask during debugging. If there is a mismatch, a leak occurs.
I wrote a category to hook background task related methods to avoid leaking being killed by watchdog:https://github.com/ruanjx/MPIBackgroundTaskProtection
More information about background task:https://medium.com/swlh/handling-background-tasks-in-ios-13-67f717d94b3d

iPhone restarts after API call

I am facing a very weird issue: my iPhone is restarting.
This issue occurs in a particular scenario only.
Step 1: I have a sync process in which I'm loading data for the whole app. So I'm basically doing a heavy API call by uploading 4-5 camera captured images and syncing the app data;
Step 2: After syncing, I'm pressing the iPhone home button to make the app go in background;
Step 3: I'm locking the iPhone screen(by using side button);
After a few seconds I'm seeing the apple logo and the phone seems to restart. This is not replicating when the app is connected in debug mode. I checked the debug navigator app is using only 125 MB of memory, disk and network values is 0%. Energy Impact is showing high, I'm not sure this is due to high energy impact. I'm facing this issue only on iOS 12.4.
The fact that the phone (or possibly just springboard) restarts, and not just your application means this is Apple's bug. You're not supposed to be able to crash iOS even if you try.
Finding a likely cause will be hard since the system is not behaving the way it's supposed to. The device's logs may have more information from things other than your app. This may be a system API breaking due to any number of actions from your application.
Often with this kind of thing the next OS version will fix it, but if that's not the case or it's important to track down I would try removing ways you're interaction with the system (background APIs, notifications, etc.) and see if anything fixes the issue.
If you find the problem, you may even be doing things the "correct" way according to the documentation and have to find a workaround. If you have the time you can submit a bug to Apple so the underlying issue has a better chance of being fixed.
It seems when your app is in the background and phone locked, Automatic Reference Counting (ARC) closes some connection or deallocates a resource that makes the iPhone restart. Are you closing all connections and removing all references once the upload is complete?
Phones do not spontaneously restart just because of an app’s actions. You’re having an issue with your phone, not with a program. You need to repair or replace the phone.

How to avoid iOS app being terminated by system too often when in background

I'm building an iOS app for iOS 8 & 9 and I am facing the problem that when the app goes to background the system is terminating it after just 2 or 3 minutes.
My testing is easy:
I kill all running apps from my iPhone.
I restart my iPhone (to ensure no other apps are taking memory).
I launch my app.
I do nothing inside my app.
I press the "Home" button, moving my app to background.
I wait doing nothing else for 2 or 3 minutes.
I open my app again and surprise, the system has terminated it and now it is restarting as a new launch.
Some comments:
The app does not use CoreLocation in background neither any other service.
I've profiled the app, trying to understand if it is consuming too much memory. When moving to background, it consumes around 25Mb of RAM memory. I'm attaching a screenshot below.
This behavior has been tested on iPhone 5, 5s, 6, 6+.
In iPhone 6s and 6s+ seems to take a bit more time to happen, but still happens.
My question is: Do you know why would this be happening? anything I might not be considering or just forgetting?
I don't want to force my app to run in background by using CoreLocation or something similar. And I'm ok if the system kills my app eventually. What I don't want is that everytime I move my app to background the system terminates it.
Any hint or help will be appreciated.
Thanks,
All applications are automatically killed by the system
According the Apple documentation:
App Termination
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.
Suspended apps receive no notification when they are terminated; the >system kills the process and reclaims the corresponding memory. If an app >is currently running in the background and not suspended, the system calls >the applicationWillTerminate: of its app delegate prior to termination. >The system does not call this method when the device reboots.
In addition to the system terminating your app, the user can terminate >your app explicitly using the multitasking UI. User-initiated termination >has the same effect as terminating a suspended app. The app’s process is >killed and no notification is sent to the app.
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html#//apple_ref/doc/uid/TP40007072-CH2-SW1
You can track position but you will certainly see a blue status bar to indicate that an application use GPS tracking.
Maybe you can try to "wake up" your app in background with silent notification...
If it is not necessary to keep your app alive, trust the system...
Some error in inside your code. Please select debug Navigator before run your app... Now you can able to find your error..
Or too much memory also it will terminated..
Apps which are running in the background drain battery life faster, It gives you a bad perception of the device, instead of the app, because the average consumer has no idea that it's an app draining battery.
Thus iOS won't allow your app to run in the background, more than a few seconds. But there are some exception, an app can request extension to this by declaring that its starting a Background Task.
for more info you can check below links:
http://blog.dkaminsky.info/2013/01/27/keep-your-ios-app-running-in-background-forever/
http://www.speirs.org/blog/2012/1/2/misconceptions-about-ios-multitasking.html

Is there a way to know if and why iOS terminated your app?

I'm trying to debug an issue with my iPhone app that seems to be getting terminated while running on the device (it never happens in the simulator). The app is for iOS 8 only.
Once app enters the background (via the user hitting the home button) I start Significant-Change Location service. When a location updates happens while the app is suspended the system should put the app in the background where I then send an update to my server with the location. That operation is wrapped in a proper beginBackgroundTaskWithExpirationHandler to allow me the time needed to make the network call.
It appears though my app is getting terminated by the system because sometimes when I resume the app from the suspended state it is no longer in the view last seen when minimizing but is back at the root controller as if starting from a fresh launch. It does not appear to be due to a crash as I do not see it in the crash log nor is New Relic reporting such. The app is suspended though, not terminated, probably because it is getting launched again into the background from a location update.
The question is, is there a way to know that my app was indeed terminated by the system, and if so, for what reason(memory, exceeding background execution time, etc.) and at what time. Is there a log kept somewhere containing this information?
I'm under the impression I can not use applicationWillTerminate because the docs say this is not called when an app is suspend.
You may check in Devices page. (Shortcut is Command + Shift + 2)

Resources