jetsam criteria for closing an app - ios

I have an iOS app connected to a peripheral and as such running in the background. Sometimes when there is a low memory situation, jetsam decides to close my app even though according to the jetsam log it is not the largest running process. So far my app didn't get any memory warnings so it is not even possible to respond to such event by releasing resources.
First I would like to know if there are any criteria for closing an app due to a low memory event.
Second, what are the keys in the log? for example the state key - does it represent the current state of the process, i.e. when it is suspended, it means that the app was closed by jetsam? or maybe that was the app's state regardless of the low memory event
Can several processes be closed? Because when I look at all JSONs, only one process has the killDelta key, and it doesn't always happen to be the largest one, and even so I can see that several processes are suspended, meaning again that not only one was closed?
I'd appreciate any help
Thank you

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.

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

iOS stops waking up the app upon incoming BLE connection from peripheral

we have a BLE peripheral that connects to the phone every hour and passes some data. Here is how the process works:
Upon launch with key UIApplicationLaunchOptionsBluetoothCentralsKey in
application(didFinishLaunchingWithOptions launchOptions) app re-initializes CBCentralManager with ID that was passed to it.
Then it goes through the regular restoration cycle and reads data off the BLE peripheral.
Performs REST request to the service in the cloud.
Assuming that app has been launched at least once after phone reboot everything works well for a few days (if app isnt running or been forced out of memory, iOS properly starts it up again, assuming user didnt do forced close manually).
However every few days iOS stops waking up the app when there is an incoming request from BLE device. If user relaunches app everything works properly for a few days and then stops agains. Given the nature of our product, it's critical to have our app / peripheral working together in the most reliable way possible.
Theories as to why it might be happening:
(upon closer examination all of them were dismissed)
Users restart the phone and forget to relaunch the app.
We've added logging of the uptime and it showed that phone didnt restart in between app launches.
Memory warnings lead to app being booted out.
Once again, added logging, they showed that there was no applicationDidReceiveMemoryWarning
Bad connection leads to app running for longer period than 10s when uploading results and iOS terminates it and gets upset
We artificially delayed server response by 15s to test this and everything continues to work properly during testing.
Any ideas on what is happening and why iOS stops notifying app about incoming BLE connection?
One of the problems is that we cannot figure out how to reliably reproduce the issue So any suggestions there will be much appreciated as well!
Thank you!
UPDATE 1:
Here is how we initialize CBCentralManager:
self.centralManager = CBCentralManager(delegate: self, queue: nil, options: [
CBCentralManagerOptionRestoreIdentifierKey : MyCentralManagerID,
CBCentralManagerOptionShowPowerAlertKey : 0])
I saw some suggestions that queue parameter should not be nil. Given that I'm unable to reliably reproduce issue I'm hesitant to make that change until I can confidently observe its effects.
I wanna start by saying that I have been working with CoreBluetooth for a long time now and from what I have noticed CoreBluetooth State Preservation and Restoration does not work reliably at all. You can get it working sort of "ok", but you will never get it to reconnect reliably unless Apple fixes it some day.
There are so many bugs that causes this to not work properly, but I will give you one that I believe is causing your problems:
State restoration will only relaunch your app due to bluetooth related activity if the event originates from a peripheral accessory that you are communicating with, such as connect/disconnect events and characteristics notifications. For other events, most importantly general bluetooth state change events, your app will not be relaunched and notified of this. The reason why this is so bad is because all bluetooth state change events will cancel all pending or current connections, meaning that pending connections will be dropped and your application will not be notified of it. This effectively means that your application will still believe that the connections are still pending when in fact they are not. Since your application is terminated at this time, the only way for it to wake up again is by having the user manually launch it again (or alternatively “hack” other background modes for this purpose, which does not work very reliably either).
This thing happens if the user toggles Flight Mode, toggles Bluetooth, power cycles the iOS device, or any other undefined reasons that many cause state changes…
But this is only one bug. Many other exists as well, such as the XPC connection being interrupted at different times for no apparent reason. I have also noticed that the pending connection can go into “limbo” mode where the peripheral state gets set to Connecting, but in fact it will never connect unless you cycle the connection state.
Anyhow, I am sad to say it, but if you are developing an app that must rely on the peripheral being reconnected in the background then I would not recommend doing it. You will be frustrated. I could probably write an essay about all the bugs in Core Bluetooth that Apple does not want to fix. Even more strange is that you can pretty easily ruin the bluetooth connectivity globally on the device from one single app so that no app can use bluetooth until the device is rebooted. This is pretty bad since it goes against Apple's own Sandboxing principle.

Will ios terminate the app running in background after a specific time?

I am using core location framework inside my application and I set the location string in UIBackgroundMode or Required background modes(in Xcode 4.2) for getting the updated location from didUpdateToLocation method when app is running in background and also sending this updated location to server by hitting the specific link inside didUpdateToLocation method of core location framework.
My question is that will the app be terminated after some time when running in background or not?
No, there is no specific time defined for this.But app will definitely terminate based upon certain parameter - battery drain, memory footprint issue etc.
In developer documentation it is clearly mentioned - "The system keeps suspended apps in memory for as long as possible, removing them only when the amount of free memory gets low. Remaining in memory means that subsequent launches of your app are much faster."
Go through this for complete details -
http://developer.apple.com/library/ios/#DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html
I am sure it is not useful for the author because the question was asked in June 2012 and I am giving an answer in June 2019. This answer maybe is useful for other users.
I am posting this answer because Everyone is said that it is OS default behaviour, We can not change it....bla....bla.
Recently, I was working with the same requirement. After 2-3 week hard
work, I did it. For other users, I create a helper class for it. My
app will never be killed by OS until the location tracking enabled.
You can also verify that OS will never kill this app tracking app
Use HSLocationManager for infinite location tracking in the active and inactive state.
Refer my app which is available in the app store(App will never kill by OS if location tracking is enabled)
Location manager that allows getting background location updates every
n seconds with desired location accuracy.
Advantage:
OS will never kill our app if the location manager is currently
running.
Give periodically location update when it required(range is between 2 -
170 seconds (limited by max allowed background task time))
Customizable location accuracy and time period.
Low memory consumption(Singleton class)
iOS app may get terminated due to following reasons:
Watchdog Timeout
As you’re probably aware, since iOS 4.x, most of the time when you
quit an iOS app, the app isn’t terminated – instead, it’s sent to
the background.
However, there are times when the OS will terminate your app and
generate a crash log if the app didn’t respond fast enough. These
events correspond with the implementation of the following
UIApplicationDelegate methods:
- application:didFinishLaunchingWithOptions:
- applicationWillResignActive:
- applicationDidEnterBackground:
- applicationWillEnterForeground:
- applicationDidBecomeActive:
- applicationWillTerminate:
In all of the above methods, the app gets a limited amount of time
to finish its processing. If the app takes too long, the OS will
terminate the app.
User Force-Quit
iOS 4.x supports multitasking. If an app blocks the UI and stops
responding, the user can double-tap the Home button from the Home
screen and terminate the app.
Note: You may have noticed that when you double-tap the Home button,
you also get a list of all the applications you’ve run in the past.
Those apps are not necessarily running, nor are they necessarily
suspended.
Usually an app gets about 10 minutes to stay in the background once
the user hits the Home button, and then it gets terminated
automatically by the OS. So the list of apps that you see by
double-tapping the Home button is only a list of past app runs.
Low Memory Termination
When subclassing UIViewController, you may have noticed the
didReceiveMemoryWarning method.
Any app that is running in the foreground has the highest priority in
terms of accessing and using memory. However, that does not mean the
app gets all the available memory on the device – each app gets a
portion of the available memory.
When total memory consumption hits a certain level, the OS sends out a
UIApplicationDidReceiveMemoryWarningNotification notification. At the
same time, didReceiveMemoryWarning is invoked for the app.
At this point, so that your app continues to run properly, the OS
begins terminating apps in the background to free some memory. Once
all background apps are terminated, if your app still needs more
memory, the OS terminates your app.
I have seen that the background location updates will work for several hours. But if I go to a place without reception the device will stop to send GPS updates it wont start when I go to a place with reception. This occurs after approximately 30min.
But if I add this, in iOS6, the app won't terminate
[locationManager setPausesLocationUpdatesAutomatically:NO];
Quick answer is pretty much no. Read below though for in depth.
Since multitasking has been enabled on iOS devices that a)your app gets allocated amount of memory and b)the device limits the amount of tasks, that is applications using memory, that occur at any given time. If you take an iOS device and open several apps you'll begin to notice that the app you opened first may have been terminated and reload from the viewDidLoad.
Generally it's safe to say if your app is a recently opened app (or even on a phone where someone clears the multitasking menu often) that the device will not terminate your application in the background.

Resources