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:
- Your app can continue scanning for peripherals in the background, but scan behavior changes. Active scanning becomes passive. You will only discover peripherals that are advertising the specific service UUIDs you specified in your scan filter. Wildcard scans return nothing in the background.
- Existing BLE connections remain active. You continue to receive
didUpdateValueForcallbacks for characteristics you have subscribed to via notifications or indications. - You can initiate new connections to known peripherals, though connection timing is deprioritized by the system scheduler.
Here is what this entitlement does not give you:
- Unlimited CPU time. Your callbacks are still subject to background execution limits. If your processing takes too long per callback invocation, iOS will throttle or suspend your app.
- Protection from app termination. iOS can and will terminate your app under memory pressure, even with the background mode enabled. On devices with 3 GB or 4 GB of RAM (iPhone 12, iPhone 13, SE 3rd generation), this happens more often than you expect.
- Guaranteed connection persistence. If the BLE connection drops (due to range, interference, or peripheral restart), your app must detect this and reconnect. The system will not do it for you automatically.
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:
CBCentralManagerRestoredStatePeripheralsKey: an array ofCBPeripheralobjects that were connected or pending connection at the time of termination.CBCentralManagerRestoredStateScanServicesKey: the service UUIDs you were scanning for.CBCentralManagerRestoredStateScanOptionsKey: your scan options.
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:
- In
applicationDidEnterBackground, callbeginBackgroundTask. - Flush any in-memory buffers to your recording file.
- Write a checkpoint marker to your data file so you can detect incomplete sessions.
- Call
endBackgroundTaskas 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:
- You declare the background mode but do not use BLE in a way that requires it. If your app only uses BLE for initial setup or configuration, you do not qualify for background mode.
- Your app scans continuously in the background without connecting to anything. Background scanning must be purposeful and filtered to specific service UUIDs.
- You use the background mode to keep your app alive for non-BLE purposes (such as location tracking or periodic network requests). Apple detects this pattern and rejects it.
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:
- BLE data recording continues for at least 60 minutes with the app backgrounded and the phone locked.
- The app reconnects automatically after a peripheral power cycle, both in foreground and background.
- State restoration works after forced app termination: data recording resumes when the peripheral reconnects.
- Memory usage in the background stays under 50 MB. Higher usage increases termination probability.
- No data is lost during the foreground-to-background transition.
- 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.