WebSocket connection in background triggered by BLE accessory

Hello everyone,

We are building an iOS app using React Native that connects to a custom Bluetooth Low Energy (BLE) accessory. The accessory continuously sends small chunks of audio data to the app through BLE (basically every time the user speaks), which are then streamed in real time to our server via WebSocket for transcription and processing.

We need to know if the following behavior is allowed by iOS runtime and App Store review policies: Can the app open a WebSocket connection in the background (not permanently, just briefly, several times a day) triggered by BLE activity from a registered accessory? Is there a limit to this?

Clarifications:

  • The app is not expected to remain permanently awake. Only during accessory-triggered events.
  • WebSocket is required due to the real-time nature of streaming STT and delivering quick responses (via notifications).

If allowed, are there any specific Info.plist declarations or entitlements we must include?

Thanks in advance!

Fran

Answered by DTS Engineer in 848206022

I can’t address the App Review side of this. For that, I recommend that you follow the advice above. However, I can discuss the technical aspects of this.

Can the app open a WebSocket connection in the background … triggered by BLE activity from a registered accessory?

Probably.

In general, iOS supports networking in the background. The key gating factor is runtime. Your app can’t do any networking while suspended [1].

When Core Bluetooth resumes your app in the background, it gives it a very short amount of background execution time, on the order of a few seconds. You may be able to extend that using a UIApplication background task [2], but still not for long. If your app can get its WebSocket work done in that amount of time, you’re all set.

However, there are two significant caveats:

  • If the iOS device has WWAN, it’ll typically shut down the Wi-Fi interface when the user is not actively using the device. That’s a problem if the server you’re connecting to is only available via Wi-Fi. For this to work, your server must be available over Wi-Fi and WWAN.
  • There’s no guarantee that the device has a working network. If not, or if the network is very slow, you need to come up with a plan for what to do when your WebSocket connection fails. It might make sense to buffer the event. Or you could choose an alternative strategy, such as using a task in a URLSession background session [3]. Or if this is a real-time event — meaning that it’s not useful if it arrives late — then the you should just discard it.

If you choose to buffer the event, make sure to do that on disk. Remember that iOS can terminate your app while it’s suspended, and in that case any in-memory buffer will disappear.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] The obvious exception is URLSession background sessions, but those are actually run by a system process on your behalf.

[2] I have lots of info about those in UIApplication Background Task Notes.

[3] Keep in mind that background sessions only support HTTP[S] tasks, so for that to work you’d have to add an alternative HTTP interface to your server.

Thank you for your post. We recommend that you sign up for a session with App Review during the weekly Meet with Apple Experts event. Sign in with your Developer ID and select "Request a one-on-one App Review consultation". A member of the App Review team will help you with your questions regarding the review process and the App Review Guidelines.

I can’t address the App Review side of this. For that, I recommend that you follow the advice above. However, I can discuss the technical aspects of this.

Can the app open a WebSocket connection in the background … triggered by BLE activity from a registered accessory?

Probably.

In general, iOS supports networking in the background. The key gating factor is runtime. Your app can’t do any networking while suspended [1].

When Core Bluetooth resumes your app in the background, it gives it a very short amount of background execution time, on the order of a few seconds. You may be able to extend that using a UIApplication background task [2], but still not for long. If your app can get its WebSocket work done in that amount of time, you’re all set.

However, there are two significant caveats:

  • If the iOS device has WWAN, it’ll typically shut down the Wi-Fi interface when the user is not actively using the device. That’s a problem if the server you’re connecting to is only available via Wi-Fi. For this to work, your server must be available over Wi-Fi and WWAN.
  • There’s no guarantee that the device has a working network. If not, or if the network is very slow, you need to come up with a plan for what to do when your WebSocket connection fails. It might make sense to buffer the event. Or you could choose an alternative strategy, such as using a task in a URLSession background session [3]. Or if this is a real-time event — meaning that it’s not useful if it arrives late — then the you should just discard it.

If you choose to buffer the event, make sure to do that on disk. Remember that iOS can terminate your app while it’s suspended, and in that case any in-memory buffer will disappear.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] The obvious exception is URLSession background sessions, but those are actually run by a system process on your behalf.

[2] I have lots of info about those in UIApplication Background Task Notes.

[3] Keep in mind that background sessions only support HTTP[S] tasks, so for that to work you’d have to add an alternative HTTP interface to your server.

Hi Quinn,

Thank you very much for your detailed and thoughtful response. It was incredibly helpful.

Just to clarify and expand on our specific use case:

We are developing a voice-based wearable (a pendant) that continuously listens for speech through its onboard microphone. The device sends audio in real time via BLE to our mobile app (React Native), which then streams the audio to our backend using a WebSocket connection. The goal is to provide immediate STT transcription and return a response via push notification, all within a few seconds.

To be clear:

  • The mobile app receives real audio data from a BLE-connected accessory.
  • We do not expect the app to remain awake indefinitely. It only becomes active when the device is actively sending audio (a few seconds here, 30 seconds there, depending on how much time the user speaks).
  • This is not synthetic audio or a hack to stay alive. It’s a legitimate voice input stream triggered by a BLE accessory and transmitted in real-time.

Given this scenario, we’re considering using AVAudioSessionCategoryRecord to keep the app alive during those audio streaming sessions. Considering this, if the app is configured with the proper background modes (audio and bluetooth-central) and is actively receiving audio via BLE, can it legally and technically keep a WebSocket connection open for the duration of that audio session, even if the phone is locked?

Any further clarification you could provide on that front, or confirmation that this approach aligns with Apple’s intended use of background execution, would be incredibly valuable for our development and planning.

Thanks again for your support and time!

Best regards,
Francisco

And just to clarify, the app only needs to be active in background while receiving data over BLE. My use case involves batch-processing audio streamed from a BLE accessory, and then either:

  • Sending it to the server in real time via WebSocket, or
  • Running a lightweight STT model locally on the phone, and then sending the resulting text to the server via HTTP.

In either scenario, the background activity only happens while BLE data is actively being received, and ceases immediately after.

To reiterate, I can’t comment on App Store policy.

Speaking technically, the audio background mode still has limitation. The one most relevant to your setup is that you have to start your audio session while your app is in the foreground.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

WebSocket connection in background triggered by BLE accessory
 
 
Q