Reducing memory size to ensure backgrounding in iOS - objective-c

When developing an app that uses Bluetooth Low Energy, there comes a time when the iOS device loses connection to the peripheral. (Sometimes for hours.)
In order to reconnect to an existing peripheral, the app must constantly scan in the background at a specific rate throughout the day(s), even when the app is backgrounded.
The problem is, iOS will not guarantee that your app will not get killed, due to memory constraints, etc.
Information found in the iPhone OS Programming guide states that:
Apps that work with Bluetooth peripherals can ask to be woken up if
the peripheral delivers an update when the app is suspended. This
support is important for Bluetooth-le accessories that deliver data at
regular intervals, such as a Bluetooth heart rate belt. When an app
includes the UIBackgroundModes key with the bluetooth-central value in
its Info.plist file, the Core Bluetooth framework keeps open any
active sessions for the corresponding peripheral. In addition, new
data arriving from the peripheral causes the system to wake up the app
so that it can process the data. The system also wakes up the app to
process accessory connection and disconnection notifications.
The problem does not arise when the phone is connected to a device and the application is background. It does happen, however, when the device is disconnected and the app is backgrounded. In this specific case, the phone is no longer connected to the peripheral, and therefore no longer getting notifications.
Many people have discussed this before, either on Stack Overflow or the Apple forums, and I believe one of the Apple developers has responded saying:
We're aware of this issue and are trying to come up with a solution.
Currently, there is no workaround."
My question is, is there a way to at least improve your chances of not getting killed by iOS due to memory constraints?
For example, an instant messaging app (IMO) seems to run quite nicely in the background. After days and days of not being used, the app will wake up and display a gChat message.
I’m questioning things such as
Strong pointers
Overall memory size
Reducing memory size when app is backgrounded or minimized
Reducing frequency of background operation
Etc.

Why do you need background execution even when the bluetooth hardware is disconnected?
I don't think that you need to "rescan continuously" to reconnect again, if the hardware is "paired" with the iPhone/iPad, it will reconnect itself. Like a bluetooth headset. Or not?
AFAIK you have no chances to accomplish what you are asking for.
A normal App is always suspended when the user go back to home. The app has approx. 5 secs of background time to stop timers, save state ecc ecc.
There are special background modes that allows you to have more background time, and each of this mode (explained in the page you linked) has a different behavior.
About the bluetooth mode:
The descripted behavior is not an issue, but it's by design:
the app is suspended
when the app is suspended, it can be killed by the OS to free ram (and there are no tricks to avoid this), but the system will wake up if needed.
the app is then awaken every time a notification is received (awaken from suspended state or lauched from "previously-killed" state)
the app has 10 seconds to do tasks (save informations, ecc ecc). Moreover, can request +10 mins. of background time for a particular task
after the 10 secs (or 10 min) the app is suspended again
The example you wrote about the chat app is incorrect: chat apps usually doesn't use any background mode, simply they forward you messages using push notifications. When you open the app, the app connect to a server that stores all your messages and download it.
You can get "more uptime" using location background mode (routing app can work in background), or using a combination of significative location changes (the app is awaken) and the 10 minutes background time, but I think that Apple will reject an app that "abuse" this.
Shortly, you have to design your app to support this behavior.

I found this in some more Apple documentation:
Memory Usage for Background Apps
Every app should free up as much memory as is practical upon entering
the background. The system tries to keep as many apps in memory at the
same time as it can, but when memory runs low it terminates suspended
apps to reclaim that memory. Apps that consume large amounts of memory
while in the background are the first apps to be terminated.
Practically speaking, your app should remove strong references to
objects as soon as they are no longer needed. Removing strong
references gives the compiler the ability to release the objects right
away so that the corresponding memory can be reclaimed. However, if
you want to cache some objects to improve performance, you can wait
until the app transitions to the background before removing references
to them.
Some examples of objects that you should remove strong references to
as soon as possible include:
Image objects
Large media or data files that you can load again from disk Any other
objects that your app does not need and can recreate easily later To
help reduce your app’s memory footprint, the system automatically
purges some data allocated on behalf of your app when your app moves
to the background.
The system purges the backing store for all Core Animation layers.
This effort does not remove your app’s layer objects from memory, nor
does it change the current layer properties. It simply prevents the
contents of those layers from appearing onscreen, which given that the
app is in the background should not happen anyway. It removes any
system references to cached images. (If your app does not have a
strong reference to the images, they are subsequently removed from
memory.) It removes strong references to some other system-managed
data caches.

From the apple documentation i have always assumed the following:
connectPeripheral:options:
Establish a connection to the peripheral.
- (void)connectPeripheral:(CBPeripheral *)peripheral options:(NSDictionary *)options;
Parameters
peripheral
The peripheral to connect to.
options
A dictionary to customize the behavior of the connection. See CBConnectPeripheralOptionNotifyOnDisconnectionKey.
Discussion
**This never times out**. Use cancelPeripheralConnection: to cancel a pending connection.'
With the important part being on the fact that this never times out. I would assume this would hand off to the system so that it will connect automatically to the peripheral when it comes into range, thus removing the need for full backgrounding. Someone correct me if im wrong though!

Related

react-native-ble-plx: BLE Scanning in iOS Background & Suspended mode

Context
IOS Background and suspended mode
Library version: react-native-ble-plx 1.0.3
Platform: iOS.
Platform logs (XCode)
Expected Behavior
When the app is even in the background or suspended mode of ios, the callback of the startDeviceScan gets invoked.
Current Behavior
When the app is in the background or suspended mode of ios, the callback of the startDeviceScan never gets invoked. I assume there is never discovery event found yet, according to the apple ble doc. Is it possible to configure the 'startDeviceScan' to make the app scan in the background and suspended mode?
After a few research, I find something helpful related with ble scanning in ios background & suspend mode.
1.) Scanning is throttled down when iOS devices are in the background.
While scanning in the foreground will likely immediately discover a device advertising next to it, discovery in the background can take up to ~60 times longer. The iOS system makes no assumptions that the user would prefer one app to have better Bluetooth functionality than another (or that only one app wants to use it). And since it is shared functionality, they want users to have a uniform experience across apps. You should check out the technical specifications regarding Advertising and Scanning intervals to get a better idea of what Apple has to do under the covers.
2.) Your devices may have already discovered each other before entering the background.
We must remember that Apple disables the CBCentralManagerScanOptionAllowDuplicatesKeyscanning flag when we enter the background. Since you're not even specifying this flag, it defaults to NO anyways. So if they've even seen each other once, you will not get another callback when they are in the background.
3.) Respect the Limits of Advertising Data
Although advertising packets in general can hold a variety of information about the peripheral device, you may advertise only your device’s local name and the UUIDs of any services you want to advertise.  There are also limits as to how much space you can use when advertising data. When your app is in the foreground, it can use up to 28 bytes of space in the initial advertisement data for any combination of the two supported advertising data keys. If this space is used up, there are an additional 10 bytes of space in the scan response that can be used only for the local name. Any service UUIDs that do not fit in the allotted space are added to a special “overflow” area; they can be discovered only by an iOS device that is explicitly scanning for them. While your app is in the background, the local name is not advertised and all service UUIDs are place in the overflow area.

How reliable is Bluetooth BLE in combination with smartphones?

We are developing a system where we can open doors with a smartphone. The chosen technique for this is Bluetooth BLE. There is an app which needs to be active in the background for providing this “handles key system”. This app recognizes and connects automatically with the door to open it.
We have a working demo on 3 different iphone models and several different android phones. The exact details of these system are not important for my question.
For our project we are in talk with some investors who says the idea is great but the Bluetooth technique is not reliable enough. The don’t say on what point it isn’t reliable enough.
We need to prove that Bluetooth IS reliable for this situation so we are looking for some best practices where Bluetooth is uses in critical situation such as a transport or health sector. Some “official” papers from a professors or university is also welcome!
We also looking aslo for examples where comparable situations where locks or something else are opened “handless” with a smartphone.
Where can we find these information, firms, papers and so on? In one line: How can we prove that Bluetooth is stable and reliable for our purposal (using a smartphone which autoconnects to some device for authentication)
I hope someone can help us else our project will be canceled!
There is nothing wrong with the BLE technology itself regarding reliability. It's rather the hardware and software implementations that will define how reliable a solution will be.
After having worked with BLE for several years I can tell that most peripheral SoC solutions are very reliable. And if they for some reason crash, the firmware is usually rebooted and restored.
Android and iOS are often the ones to blame if something isn't reliable. The Bluetooth stack running on these OSes crash quite often or misbehave and it can be hard to recover from.
For Android, sometimes Bluetooth crashes and when you try to turn it on again in it just goes back to turned off state. To recover you have to reboot the phone. I must however say that if you manage to initiate a connection and don't get any errors it will often continue to run correctly. To avoid the Android system to kill your app while it's in the background you have to use a foreground service. On some phones, like Huawei, the user must also explicitly mark the app to not being killed by the system when it's running in the background. For Android, there are also many phones with different Bluetooth controllers and some have bugs other controllers don't have. For example I once got hand on a Sony Xperia Z3 phone which Bluetooth controller cancelled a pending connection when an LE scan (running in parallel) was cancelled, but according to the HCI log the pending connection was still going on. The peripheral was advertising but was never connected to the phone. Once the pending connection was explicitly cancelled and restarted, it connected immediately.
iOS is more problematic than Android if you want BLE to work in the background. iOS will kill your app when it has been in the background for some time. To get around that, they have something called "state preservation" which is their solution to wake up the app on an incoming Bluetooth event such as the peripheral connects or sends a notification. However there are many bugs and design decisions which will lead to that your app isn't being woken up. For example see https://forums.developer.apple.com/message/65953. If your app has been terminated and the user turns off and then turns on bluetooth (or the system restarts bluetooth due to internal errors), your app will not be woken up on an incoming Bluetooth event. Also, if a bug occurs in the Bluetooth stack (which happens quite frequently), your app will not be woken up and all the events will rather arrive to your app once the user manually opens it up.

Keep App Alive in Background IOS7

I have created the application, which track the GPS Location of user at specific time period. This process is run 3 times in background. So, App need to keep alive in background.
To achieve the our requirement, we use the Location manager (GPS) running in the background. So, it will never been killed by OS. Also, we have run the background task thread while App is in background.
This approach working fine on iOS 6 and before and running more than 10 minute in background.
But in iOS 7 Application going to killed after 10 minute.
Please need suggestion for keep the Timer alive in background.
We would appreciate the earliest response. Thank you in advance.
How to keep app running alive in background in IOS 7 without affecting the battery life.
There's no reason for the app to be killed if it has background location tracking functionality in the Info.plist file and doesn't try to abuse the benefits of that permission.
I'm not sure what's your use case for the tracking functionality, but -- together with an assumption that if there's no record from some period, the tracked device didn't change the location -- setting a distance filter would allow to track the location all the time.
That also allows to put a smaller burden on device's battery, because in certain activity types handled by CLLocationManager, the device may put the location service in idle state if it doesn't detect any significant movement.
if you want to keep app active in background and don't want to go to appstore for some reason (for example you are developing something for your company with using enterprise developer program), you should check deferredLocationUpdates(even on devices which doesn't support them, you just get error in your delegate but app will work) and don't call stopLocationUpdates while in background.(if you use this on app for appstore you have to explain why you needed this to apple of course).

Symbian App life cycle: Apps never killed?

Coming from Android/WP7 and having been involved in Symbian projects by the past, i would like now to exactly understand the Symbian App life cycle. I want to understand how the Apps are killed.. if they are..
I found this:
"The Symbian platform is a modern preemptive multitasking operating system. Applications are created in their own process, running in a single main thread. The kernel preemptively schedules all threads in the system, based on their priority. While it is possible to create secondary threads, Symbian strongly encourages applications to co-operatively multi-task using active objects. ". Ref-link
"(..) applications may be up and running at the same time and the user may switch between active applications. When a asynchronous event occurred, running application is moved to the background but it remains active". Ref-link
It seems to me that the Apps are never killed, even when they are in background..
My question is: If the system does not kill them, how the system deals with the RAM issue? What about the possible battery drain? Does it mean that Symbian allows starting each single App, till there is not enough memory? Is there a specific meaning about the use of the Cancel/Back key that might destroy the App in certain conditions?
In UIQ framework i remember a lowMemory() call-back, but one never used that..
Thanks, for your help..
Symbian Apps are indeed never killed. That allows you to have several apps running in parallel without problems. Every app should of course provide the Exit command that closes the app. Back/Hide command just leaves the app runnning and takes user back to the menu. Also every well-written app should also manage his background tasks and allow to stop them when needed.
FYI, in Symbian there might be several background tasks running that are automatically started when phone is powered on. You can get the list of them when asking for a list of processes. You can also kill any process or app if your app has enough capabilities.

Need iOS reference for what happens in sleep, standby and/or idle modes

I'm a new ObjC dev and after searching the Web and Apple's developer docs, I can't find a good succinct explanation of the various iOS device modes, and what goes on in these modes. I see a lot of little discussions, but nothing overarching about the big picture.
For example, I see that some Alarm applications for iPhone/iPad claim to be able to execute alarms (presumably not just system alerts) in the morning. I'm struggling to understand how that happens, even if the user lets the app just keep running overnight, assuming the device goes into sleep mode after no use.
So I don't know what happens when the device goes into sleep or standby mode. Is it just the screen dimming? Does the application in the foreground continue to execute code, go into some interim state like background mode in a saved state, or does it completely (even if temporarily) shut down?
I'd just like to be pointed to a website, a book or the portion of the Apple documentation that explains the various device states, what's going on under iOS 3 & 4 with the application in each state, and how to manage that if you'd like to build an app similar to a simulated bedside alarm clock that's "always on," etc.
Thanks in advance.
Those 'alarms' are Local Notifications, and are very handy. They're fired even when an application is closed, and even when the device is asleep.
The concept of asleep is not too tricky; when the user 'quits' your application (pressing the home button), your application will either be halted and placed into a frozen state (4.x), or quit entirely (3.x). Nonetheless, you are given the opportunity to do a few cleanup operations before the latter happens with the - (void)applicationWillTerminate:(UIApplication *)application method, and before the former happens with the - (void)applicationDidEnterBackground:(UIApplication *)application method (both are called upon your delegate class).
The concept of 'sleep' means that in both iPhone OS 3 and iOS 4 you'll receive the following method when your app loses focus (and also when an SMS comes in, or an alert, etc):
- (void)applicationWillResignActive:(UIApplication *)application
Really, most applications (with the exceptions of applications that are designed to work in the background, like voip, audio streaming, etc) simply quit on close. But if you need to, you can also suspend the freezing of your app and ask for more time to complete a task.
This was a lot easier to grasp in the 3.x days, but now with 4.x's 'multitasking' it becomes a bit harder. It's not too daunting though, and a read of this will help a bit.
This may be of help:
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html
see the applicationState for UIApplicationState.