Implement BLE scan in the background in iOS - ios

I have a query regarding Scanning of the BLE devices in an iOS app.
Use case of our app is to share the location of a set of BLE devices assigned to each user continuously to a particular server for every 15 minutes time interval, irrespective of the state of the app (except terminated state may be).
About our BLE device, it transmits the advertisement data once for every 4 second interval.
We tried using the "uses Bluetooth LE accessory" background mode and continuously we were able to scan the BLE devices using the scanForPeripharal method in CBCentralManager with the UUIDs of the BLE devices.
We were able to get the list of scanned devices even in the background.
But when we lock the device and the screen becomes inactive/turned off, we are unable to get the list of scanned devices.
In another solution, we tried using the background fetch but it is very inconsistent(practically it never gets called in the given time interval).
We need a solution using which we should be able to do the following,
For every 15 minutes time interval.
scan the BLE peripherals around our vicinity.
Get the current location of the user.
Share it with a MQTT server.

A couple of options:
If you have a custom BLE device anyway, you could modify it to send a stream of iBeacon advertisements periodically, say a burst of 10 packets every 15 minutes. An app looking for the iBeacon using CoreLocation would wake up in the background every 15 minutes and you could then read your other advertisements with CoreBluetooth.
You could make your app request location background modes, and request fine location updates. This may allow you to get BLE device discoveries after receiving callbacks for location update events. The disadvantage is that you would need to satisfy the AppStore reviewers that your app is a consumer navigation app to get it in the AppStore.

Related

Scan and Connect iPhone to BLE sensor when the iOS device is in Background

I want to connect to the BLE sensor every hour to my iOS device for transmission of data from the sensor to an iOS device. If the app is in foreground everything is fine from Discovery to Connection to Read/Write of data. After Reading/Writing to my BLE sensor, I disconnect the iOS device from the sensor and sensor goes to sleep.
Now when the next sync cycle comes (i.e. next hour) and the app is in the background I need to again scan for the peripheral and read data from it. Is it possible to give a command to scan for peripheral when the app is in the background?
I have enabled background modes as bluetooth-central.
I have implemented all delegates of CBCentralManager but did not get any callback when app is in background and peripheral is advertising data. (-didDiscoverPeripheral, or -didConnectPeripheral)
So my question is:
When my app is in the background where should I pass the command (scanForPeripheralsWithServices) by providing respective service UUIDs?
Is there a way by which I can scan BLE devices in the background continuously or on a certain schedule like every hour?

Bluetooth low energy background

I am working on an iOS Bluetooth LE application. First I pair the IOS (central) to my bluetooth chip (peripheral)
1) Discover peripherals.
2) Connect to peripheral.
3) Getting services and characteristics.
4) Able to read data and write data from the characteristics.
5) Save the peripheral
6) Disconnect from the peripheral
When I run the app the second time, it connects to the peripheral automatically and writes and reads data from the characteristic and disconnects from it. The App works in the background for 10 minutes.
I would like to run this app in the background. That is I want to call the methods which connect, write and read values in the background every 6 hours. Is this possible? My App works in the background for only 10 minutes. Any suggestion will be of great help.
First you will need to be sure that you added:
<key>UIBackgroundModes</key>
<array>
<string>bluetooth-central</string>
<string>bluetooth-peripheral</string>
</array>
to your Info.plist which will allow your app to run in the background.
However this will work as follows: it will allow your app to "wake up" to any bluetooth event and run methods that you like to fire when your app is getting any bluetooth activity.
So for example:
you can scan for bluetooth devices in the background and once found something that fits your criterias you can run code, as didDiscoverPeripheral fires (connect / read / write etc..).
you can be connected to a device and subscribed for notification from a specific characteristic. Once the characteristic changes value your app in the background should get a notification and didUpdateValueForCharacteristic callback will be called so again you can call methods from this point, still running in the background.
maybe you can think of other use-cases. I've mentioned these scenarios to give you an idea how you can definitely work in the background with BTLE.
These scenarios should not be limited to the 10 minutes timeframe.
However I have noticed that if you run something else in background mode (e.g: a loop) and the 10 minutes passes your app might be killed from the background so even the above mentioned callbacks will not work.
So to answer your 6 hours question: it would be possible if your BTLE device could initiate some BLE action every 6 hours to wake your app up. OTherwise I'm not sure you can start your activity from the app (ios) side.

IOS: Can I periodically scan for dynamically changing BLE advertisement records in background?

Here is my scenario ..
I have a device that advertises dynamic data per BLE protocol. There are multiple such devices operating for a user
Questions -
1) Can IOS scan such constantly changing advertising data or does it expect advertising packets to be pretty static?
2) Can we create a service that scans for such packets periodically - maybe 30s every 5 minutes?
3) Can such a service be automatically restarted during bootup without user intervention?
You cannot create a service on a normal (non-jailbroken) phone. Isn't even possible to distribute something like that (read the app review guidelines). Sure, you can scan for BLE data on whatever interval you want, but your app needs to be active, or it needs to be doing something approved by Apple for making connections to BLE devices in the background. Just be aware that like any other background app, iOS might suspend or terminate your app at any time, and there's nothing you can do about it.
What you have described is covered by the standard BLE background mode - it is covered in the Core Bluetooth programming guide.
You can set up a scan for specific service UUIDs and this will continue in the background. Your app will be launched into the background when a device is discovered.
The exact scheduling of the notification can't be controlled - but in my experience you are notified pretty much as soon as a new peripheral is discovered. Once you have discovered a device you can even initiate a connection as soon as it disconnects (ie goes out of range) - iOS will automatically reconnect to the device when it comes back into range
In order for the scan or pending connection to survive across reboots you must configure state restoration. This is also covered in the Core Bluetooth Programming Guide.

iOS: detect app users nearby

I want to build and app which can detect other iPhones with my app within 65 feet range. As I understand I have the following choices:
Use Bluetooth to check periodically whether there is device with my app in the range. Send list of found devices to the server. The problem here is battery consumption. Is it true that Bluetooth will be disabled after some period of time automatically?
Can I use BLE technology for this purpose? If so, do you know what devices support BLE?
What is the best option on your opinion? Did I miss some other option?
Thanks
UPDATE
I plan to run search every 20 seconds or even more often.
There is no simple answer to this problem.
Bluetooth has 2 flavors: "Regular" bluetooth, used for hands-free devices, headphones, and the like, and BLE (Bluetooth Low Energy)
Regular bluetooth devices must be paired. (I'm less familiar with regular bluetooth than BLE, so take my explanation of this bit with a grain of salt.) In order to be paired they have to be put into "discoverable" mode, which broadcasts their ID. That is a battery-draining and only done briefly. It's not an "always on" solution.
BLE has a range of up to 60 meters, so it should meet your need in that regard.
BLE devices can "advertise" as a "peripheral" for extended periods. Other Bluetooth devices can act as a "central" and ask to be notified when certain peripheral devices are detected. I'm not sure if you can make an iOS device advertise (broadcast) as a BLE peripheral while it's in the background and/or if the device is locked, but it will certainly advertise while it's running. I'm pretty sure you can register to be notified when you detect a certain BLE peripheral from the background, but not positive.
iBeacons are a specific use of BLE with some extra limitations and some extra abilities. An iBeacon is a dirt-simple transmitter that sends a UUID plus a major and minor value and a signal strength calibration value periodically (usually once a second.) You can't add any other data to an iBeacon transmission. iOS can only act as an iBeacon transmitter when the app is in the foreground. If your app moves to the background, it stops transmitting. Period.
However, you can listen for iBeacon signals even from the background. AND, if you've registered as a listener for an iBeacon and the system terminates your app due to low memory, the system still listens for those beacons on your behalf. If iOS detects a beacon you're listening for, you get re-launched if needed, and notified in the background. You can then post a local notification to get the user's attention.
iBeacons are probably your best bet, but you will need your users to be actively running your app in the foreground in order to transmit a signal. That will drain your user's battery fairly quickly.
One possible solution would to have have every single device send their locations to your server every predetermined time period (more frequent the better but more resource intensive). Then, query the data from the server and get the location of all the devices near you.
Keep in mind, that this probably won't be very useful for real-time data collection. For example, if you want to send data every 30 seconds or so, this isn't a good option.
Use this option if you want to get data every 15-20 minutes or so.

iOS app scan BLE device on background

my app using scanForPeripheralsWithServices: to scan BLE device,the argument is specified servicesUUIDs array, sometimes could discover peripheral quickly,but sometimes need to wait for a moment.And my app is session backgrounding.Then,how can I discoverPeripherals as quickly as possible on background.
When the app is in the background iOS is enabling Bluetooth from time to time and it is not always listening. This is to save battery and because the WiFi and Bluetooth share the same antenna and cannot send at the same time. To make it discover your peripheral as fast as possible you should if you have access to peripheral implementation, make sure the peripheral advertises itself as often as possible. I believe Apple recommends at least once each 20th ms.

Resources