Why Most Biometric Wearable Apps Fail at Background BLE on iOS

Your biometric wearable works perfectly in the foreground. The BLE connection is stable, data streams in at full rate, and the UI updates smoothly. Then the user locks their phone, opens Safari, or switches to another app. Within minutes, the connection drops, data stops recording, and your support inbox fills with complaints. This is the most common failure mode in wearable health and neurotech apps on iOS, and it is entirely preventable if you understand how Core Bluetooth actually behaves in the background.

Apple designed iOS background execution with a clear priority: battery life comes first. Every mechanism available to background apps is constrained, throttled, or time-limited. BLE is no exception. But Apple also recognizes that health and fitness peripherals need persistent connections. The tools exist. Most teams simply use them incorrectly.

Core Bluetooth Background Modes: What They Actually Do

iOS provides two background mode entitlements for BLE: bluetooth-central and bluetooth-peripheral. For a wearable companion app, you need bluetooth-central. Adding this to your Info.plist under UIBackgroundModes tells iOS that your app needs to communicate with BLE peripherals while backgrounded.

Here is what this entitlement gives you:

Here is what this entitlement does not give you:

State Preservation and Restoration

This is the feature that separates apps that work reliably from apps that do not, and most developers either skip it or implement it incorrectly.

Core Bluetooth's state preservation and restoration system allows your app to recover BLE connections even after iOS terminates it. When your app is terminated, the system saves the state of your CBCentralManager: pending connections, connected peripherals, and discovered services. When a BLE event occurs (such as the peripheral reconnecting), iOS relaunches your app in the background and delivers the saved state through the willRestoreState delegate method.

How to Implement It Correctly

First, initialize your CBCentralManager with a restoration identifier:

CBCentralManager(delegate: self, queue: bleQueue, options: [CBCentralManagerOptionRestoreIdentifierKey: "com.yourapp.centralmanager"])

The identifier must be a stable string that does not change between app launches. Do not use a UUID or any value generated at runtime.

Second, implement the centralManager(_:willRestoreState:) delegate method. This method is called instead of centralManagerDidUpdateState when your app is relaunched by the system. The state dictionary contains:

The critical step that many teams miss: you must re-set the delegate on each restored CBPeripheral object and re-subscribe to characteristics. The restored peripheral objects are valid, but their delegate references are nil after restoration. If you do not reassign delegates, you will have a connected peripheral that silently drops all incoming data.

Testing State Restoration

You cannot test state restoration by simply backgrounding your app and waiting. iOS does not terminate backgrounded apps deterministically. To test reliably, use the following approach: connect to your peripheral, background the app, then use Xcode's Debug menu to simulate a memory warning followed by terminating the app from Xcode (not from the iOS app switcher). When the peripheral sends a notification, iOS should relaunch your app and invoke willRestoreState. Verify that data recording resumes without user intervention.

The 10-Second Background Task Limit

When your app transitions to the background, you get a brief window to complete in-progress work. You can request additional time using beginBackgroundTask(withName:expirationHandler:). iOS grants approximately 10 seconds (down from 30 seconds in older iOS versions, and further reduced from the 180 seconds that existed before iOS 13).

This 10-second window is not for ongoing data processing. It is for cleanup: flushing buffers to disk, saving state, and completing any in-progress network requests. Do not use it as a mechanism to extend background processing. iOS monitors your CPU usage during this window and will penalize your app (through reduced background time in future transitions) if you abuse it.

What to Do Instead

For biometric wearable apps, the background task window is useful for exactly one purpose: ensuring your last batch of received BLE data is written to persistent storage before the system potentially suspends your app. Structure your data pipeline so that writes happen continuously (not batched), and use the background task only as a final flush.

Our recommended pattern:

  1. In applicationDidEnterBackground, call beginBackgroundTask.
  2. Flush any in-memory buffers to your recording file.
  3. Write a checkpoint marker to your data file so you can detect incomplete sessions.
  4. Call endBackgroundTask as soon as the flush completes. Do not hold the task open for the full 10 seconds.

After this background task completes, your app continues to receive BLE callbacks (because of the bluetooth-central background mode), but your processing budget per callback is limited. Keep your didUpdateValueFor handler fast: parse the packet, append to a memory-mapped file, and return. No FFT computation, no UI updates, no network calls.

Reconnection After Disconnection

BLE connections drop. Range changes, interference spikes, and peripheral firmware bugs all cause disconnections. Your app must handle reconnection automatically, and the approach differs between foreground and background.

In the foreground, call connect(_:options:) on the disconnected peripheral in your didDisconnectPeripheral delegate method. Core Bluetooth will queue the connection request and connect when the peripheral is available. There is no timeout on this request. It remains active until you cancel it or the peripheral is discovered.

In the background, the same approach works, but connection timing is deprioritized. iOS may take 30 seconds to several minutes to complete a background reconnection, depending on system load. There is nothing you can do to accelerate this. Do not attempt to work around it by starting and stopping scans. That approach wastes power and does not improve timing.

The important design implication: your peripheral's firmware must buffer data during disconnection and retransmit missed samples upon reconnection. If your peripheral discards data when the connection drops, background reconnection delays mean guaranteed data gaps. Design a simple protocol where the app sends a "last received sequence number" after reconnection, and the peripheral replays any buffered samples from that point forward.

Common Mistakes That Cause App Store Rejection

Apple reviews apps that use the bluetooth-central background mode carefully. They will reject your app if:

In your App Store review notes, explain clearly why your app needs background BLE: "Our app maintains a continuous connection to a biometric wearable device to record EEG/heart rate/other physiological data during sessions that last 30 minutes or longer. Users frequently switch to other apps during recording sessions." Be specific about the peripheral type and the user scenario.

Practical Checklist

Before shipping a wearable companion app on iOS, verify the following:

  1. BLE data recording continues for at least 60 minutes with the app backgrounded and the phone locked.
  2. The app reconnects automatically after a peripheral power cycle, both in foreground and background.
  3. State restoration works after forced app termination: data recording resumes when the peripheral reconnects.
  4. Memory usage in the background stays under 50 MB. Higher usage increases termination probability.
  5. No data is lost during the foreground-to-background transition.
  6. The app does not crash on relaunch via state restoration (test on a cold start with no UI visible).

If any of these tests fail, your users will experience data loss. Fix them before release.

Background BLE on iOS is one of the trickiest aspects of wearable app development, and getting it wrong means lost data and frustrated users. DEVSFLOW Neuro specializes in building reliable companion apps for biometric wearables and neurotech devices. Visit neuro.devsflow.ca to see how we can help your team ship with confidence.