CoreBluetooth in the background at the scheduled time

Problem: I need to remain disconnected from the BLE peripheral device, but send data, data to the server, for processing as often as possible, as this is potentially critical. In other words, I want to connect every so often and send synchronized data to the API, while remaining disconnected at any other time in order to save battery life.

Failed attempt: Setting the UIBackgroundModes field of my application Info.plist file to bluetooth-central gives me background execution during my connection. I want to stay disconnected, but reconnect at predefined intervals, and also schedule an alarm from the background.

Perhaps: I noticed that the FitBit Flex application has settings in its settings to enable synchronization in the background. I'm not sure that it will ever disconnect from my Flex while it is in range, but judging by its small size, I believe that it does not stay connected.

+6
source share
3 answers

I know that I already accepted the answer for this (sorry!), But I found a solution:

 [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:60*5]; // Every 5 minutes, minimum 

in

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

and adding fetch to UIBackgroundModes , which iOS then calls:

 - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler 

every 15-240 minutes (yes, it changes a lot, but it's better than nothing). Each time I get called to fetch, I connect to the periphery, synchronize and send my data to the server, and then disconnect. Since I send this data from the BLE peripheral to the server for processing / storage, I assume this is a legitimate (AppStore worthy) use of fetch .

CAVEAT: application:performFetchWithCompletionHandler: will not be called until iOS sets a user usage pattern for the application. In other words, you need to maintain the application (do not delete it) for about 24 hours or so before the application:performFetch... method is called. Boy, it took a while to figure it out!

UPDATE: Apple accepted my application that used this solution (approved in May 2014).

+7
source

You can not. The background application cannot start any transactions, it can only respond to incoming requests (data notifications, connection events ...). In the background, the application does not work effectively, and even in the case of BLE events, it only has 8 seconds to return to sleep, otherwise it completely stops to violate the policy.

The only time your application can stay alive for a while is when it uses the beginBackgroundTaskWithName:expirationHandler: API. But even in this case, he has only 10 minutes to complete or he is killed.

If you want to sync in the background, the transaction must be running on the external peripheral side. The easiest way to stay in touch and send a notification is central once in a while. This will awaken him, and he will be able to continue reading the characteristics he needs. But there are several other ways to implement it. The ultimate solution must be designed to best suit your needs. If you have a specific idea, submit it as a separate question.

+1
source

https://developer.apple.com/hardwaredrivers/BluetoothDesignGuidelines.pdf

I'm sure you saw it, but just in case you did not. Perhaps you can save energy at the peripheral end of the BLE by increasing the connection interval (page 22).

+1
source

Source: https://habr.com/ru/post/957083/


All Articles