Bluetooth peripheral connected to iOS doesn't work in the background

Samuel Clay

I’m having an issue with a bluetooth peripheral working with a backgrounded iOS app. I need the app to respond to all bluetooth notifications in real-time. I’ve followed Apple's CoreBluetooth background process guide and it works around 10% of the time my app is backgrounded, but the other 90% of the time the events are queued and sent to my app in batches every 10 minutes.

I just need to fire a quick local subnet network request over wifi after a bluetooth event, so it takes well under the 10s iOS gives apps to work in the background.

As for CoreBluetooth settings, I followed the guide to the letter, and it does work in the background occasionally. But it also batches up notifications and re-launches my app every ten minutes, which makes me think it is configured correctly.

I can confirm the app isn’t being killed. I can keep the debugger attached and it continues to run. In fact, the debugger shows that the notifications get queued and the app enters the foreground every ten minutes. It does work for a few minutes after I use the app. But it inevitably gets fully backgrounded.

I would expect the app to be woken up as soon as a bluetooth notification comes in. Checking the connected devices list in the iOS Settings > Bluetooth screen shows a connected peripheral. And it's clear iOS is capturing the notifications. But it rarely wakes the app to send the notifications.


UPDATE Aug 10th, 2016:

So the issue is not in the device itself. It stays connected and even iOS's Settings app shows the device is still connected. I realized though that I had beginBackgroundTaskWithExpirationHandler running on applicationWillResignActive, which was giving me pseudo-background activity. When I commented that out, the app no longer un-suspends on bluetooth notification from my device.

All of the bluetooth notifications are queued and all immediately fire when the app is re-launched manually. Debugging the app shows no activity when the app is in the background. So now it just looks like I haven't configured the app to correctly work with Bluetooth in the background.

So my hunch is that something is mis-configured in following the CoreBluetooth background doc. But there's only a few steps and I have implemented each of them. I would expect launchOptions?[UIApplicationLaunchOptionsBluetoothCentralsKey] to be sent to application(_:didFinishLaunchingWithOptions:), but it is never sent. And centralManager(_:willRestoreState:) is never called.

I have "Uses Bluetooth LE accessories" enabled.

Uses Bluetooth LE accessories

I'm using CBCentralManagerOptionRestoreIdentifierKey:

manager = CBCentralManager(delegate: self, queue: nil, options: 
                           [CBCentralManagerOptionRestoreIdentifierKey: "TTcentralManageRestoreIdentifier",
                            CBConnectPeripheralOptionNotifyOnDisconnectionKey: NSNumber(bool: true),
                            CBConnectPeripheralOptionNotifyOnConnectionKey: NSNumber(bool: true),
                            CBConnectPeripheralOptionNotifyOnNotificationKey: NSNumber(bool: true)])

I'm subscribing to the characteristic notification:

func peripheral(peripheral: CBPeripheral, didDiscoverCharacteristicsForService service: CBService, error: NSError?) {        
    if service.UUID.isEqual(CBUUID(string: DEVICE_V2_SERVICE_BUTTON_UUID)) {
        for characteristic: CBCharacteristic in service.characteristics! {
            if characteristic.UUID.isEqual(CBUUID(string: DEVICE_V2_CHARACTERISTIC_BUTTON_STATUS_UUID)) {
                peripheral.setNotifyValue(true, forCharacteristic: characteristic)
                let device = foundDevices.deviceForPeripheral(peripheral)
                device?.buttonStatusChar = characteristic
            } else if characteristic.UUID.isEqual(CBUUID(string: DEVICE_V2_CHARACTERISTIC_NICKNAME_UUID)) {
                peripheral.readValueForCharacteristic(characteristic)
            }
        }
    }
    ...
}

UIApplicationLaunchOptionsBluetoothCentralsKey is never called.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    ...
    let centralManagerIdentifiers = launchOptions?[UIApplicationLaunchOptionsBluetoothCentralsKey]
    if centralManagerIdentifiers != nil {
        print(" ---> centralManagerIdentifiers: \(centralManagerIdentifiers)")
    }
    ...
}

Finally, centralManager(_:willRestoreState:) is never called:

func centralManager(central: CBCentralManager, willRestoreState dict: [String : AnyObject]) {
    manager = central
    let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey] as! [CBPeripheral]
    print(" ---> Restoring state: \(peripherals)")
    ...
}
Samuel Clay

Figured it out. Let’s play spot the bug...

class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {

    var window: UIWindow?
    var bluetoothManager = TTBluetoothManager()

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        ...
        return true
    }
    ...   
}

See that var bluetoothManager = TTBluetoothManager() line? It should be a var bluetoothManager: TTBluetoothManager! and bluetoothManager = TTBluetoothManager() should be in application(_:didFinishLaunchingWithOptions:)

That did the trick and now my Bluetooth device runs in the background.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Bluetooth peripheral connected to iOS doesn't work in the background

From Dev

Connected peripheral in background mode (Core Bluetooth)

From Dev

Connected peripheral in background mode (Core Bluetooth)

From Dev

iOS 7 Core Bluetooth Peripheral running in background

From Dev

Making ios7 BLE peripheral to work in background

From Dev

Sixaxis (PS3 Controller) doesn't work correctly connected with Bluetooth

From Dev

Bluetooth app doesn't work

From Dev

HAL libraries doesn't work correctly with USB and CAN peripheral

From Dev

Central writing characteristic to Peripheral (iOS Core Bluetooth)

From Dev

iOS App Bluetooth cannot connect to peripheral device

From Dev

How to detect click event of connected Bluetooth peripheral device (Selfie stick)?

From Dev

BlueZ/Pybluez - Bluetooth LE scan while connected to peripheral

From Dev

How to detect click event of connected Bluetooth peripheral device (Selfie stick)?

From Dev

Bluetooth doesn't work in debian 10

From Dev

iOS Swift - Reload location function with NSTimer for app background doesn't work

From Dev

iOS background Audio Stream (m3u) doesn't work on device (but does in simulator)

From Dev

iOS Swift m3u8 background play doesn't work

From Dev

Get MAC address of bluetooth low energy peripheral in iOS

From Dev

iOS: Bluetooth LE peripheral no longer updating after coming back into range

From Dev

Can iOS re-connect to Bluetooth LE peripheral by specifying )CBPeripheral *)peripheral instead of doing retrievePeripherals?

From Dev

Can iOS re-connect to Bluetooth LE peripheral by specifying )CBPeripheral *)peripheral instead of doing retrievePeripherals?

From Dev

Background-size doesn't work

From Dev

Gradient background doesn't work in some Devices

From Dev

NSTimer doesn't work in background on device

From Dev

Transition on background-size doesn't work

From Dev

setting a JFrame background, why this doesn't work?

From Dev

set css background doesn't work in firefox

From Dev

background:url("javascript:...") doesn't work anymore?

From Dev

Background of Div with list doesn't work

Related Related

  1. 1

    Bluetooth peripheral connected to iOS doesn't work in the background

  2. 2

    Connected peripheral in background mode (Core Bluetooth)

  3. 3

    Connected peripheral in background mode (Core Bluetooth)

  4. 4

    iOS 7 Core Bluetooth Peripheral running in background

  5. 5

    Making ios7 BLE peripheral to work in background

  6. 6

    Sixaxis (PS3 Controller) doesn't work correctly connected with Bluetooth

  7. 7

    Bluetooth app doesn't work

  8. 8

    HAL libraries doesn't work correctly with USB and CAN peripheral

  9. 9

    Central writing characteristic to Peripheral (iOS Core Bluetooth)

  10. 10

    iOS App Bluetooth cannot connect to peripheral device

  11. 11

    How to detect click event of connected Bluetooth peripheral device (Selfie stick)?

  12. 12

    BlueZ/Pybluez - Bluetooth LE scan while connected to peripheral

  13. 13

    How to detect click event of connected Bluetooth peripheral device (Selfie stick)?

  14. 14

    Bluetooth doesn't work in debian 10

  15. 15

    iOS Swift - Reload location function with NSTimer for app background doesn't work

  16. 16

    iOS background Audio Stream (m3u) doesn't work on device (but does in simulator)

  17. 17

    iOS Swift m3u8 background play doesn't work

  18. 18

    Get MAC address of bluetooth low energy peripheral in iOS

  19. 19

    iOS: Bluetooth LE peripheral no longer updating after coming back into range

  20. 20

    Can iOS re-connect to Bluetooth LE peripheral by specifying )CBPeripheral *)peripheral instead of doing retrievePeripherals?

  21. 21

    Can iOS re-connect to Bluetooth LE peripheral by specifying )CBPeripheral *)peripheral instead of doing retrievePeripherals?

  22. 22

    Background-size doesn't work

  23. 23

    Gradient background doesn't work in some Devices

  24. 24

    NSTimer doesn't work in background on device

  25. 25

    Transition on background-size doesn't work

  26. 26

    setting a JFrame background, why this doesn't work?

  27. 27

    set css background doesn't work in firefox

  28. 28

    background:url("javascript:...") doesn't work anymore?

  29. 29

    Background of Div with list doesn't work

HotTag

Archive