Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Background Scanning for BLE in Swift

I am attempting to have my app scan for BLE devices in the background and to search for a bit of advertisement data in Swift. I've been unable to find any tutorials or questions on here that cover this.

Basically, is there a way of doing this automatically in the background when the app isn't in the foreground and when the user has restarted their phone?: Obtaining Bluetooth LE scan response data with iOS

I hope you can point me in the right direction. Thank you

like image 972
user3246092 Avatar asked Jul 25 '15 22:07

user3246092


1 Answers

Step 1: Enable bluetooth background mode for your projects capabilities

enter image description here

Step 2: Make sure the appropriate stuff was added to your info.plist file

enter image description here

Here is the plist code if it didn't add it:

<key>UIBackgroundModes</key>
 <array>
  <string>audio</string>
  <string>bluetooth-central</string>
 </array>

Then, when you call "scanForPeripheralsWithServices" on your CBCentralmanager you have to specify an array of services to scan for. You can't pass it an empty array. It will still scan if you pass nil, just not in the background.

So specify an array of service UUID's like this:

let arrayOfServices: [CBUUID] = [CBUUID(string: "8888")]
self.myBluetoothManager?.scanForPeripheralsWithServices(arrayOfServices, options: nil)

Now if you care about options you can pass a dictionary of options in place of the nil I passed above. Mostly, this is used to specify if you want to continuously see a devices RSSI before you connect or if you just want the advertisement packet once. Put a:

println(advertisementData["kCBAdvDataLocalName"] as! String) 
println(advertisementData["kCBAdvDataManufacturerData"] as! NSData)

in the "didDiscoverPeripheral" delegate method to observe the different behavior.

Here is the Dictionary you will pass if you want duplicate keys:

let dictionaryOfOptions = [CBCentralManagerScanOptionAllowDuplicatesKey : true]
self.myBluetoothManager?.scanForPeripheralsWithServices(arrayOfServices, options: dictionaryOfOptions)

Now Apple says that when your app goes in the background mode it defaults this scan option to false but as of iOS 8.3 I have see it keep scanning with duplicate keys.

One final note on background execution. If the iOS decides to suspend your app the scanning stops. I have seen this happen as soon as 30 seconds if there are a bunch of apps running.

like image 74
Jon Vogel Avatar answered Sep 28 '22 00:09

Jon Vogel