Configuring WebSocket API for watchOS App

Hi all,

I’m developing a watchOS app that uses a WebSocket API to process voice audio. However, I keep encountering this error when trying to establish the connection:

nw_endpoint_flow_failed_with_error [C1 <server URL>:443 failed parent-flow (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6, proxy)] already failing, returning

I’ve read Technical Note TN3135, which outlines an exception for audio streaming apps. My app is an audio streaming app, and I’ve already added background audio mode to the app’s capabilities. However, I’m not sure what else is required to meet the exception described in TN3135.

Questions

  1. How do I meet the exception outlined in TN3135 for WebSocket audio streaming on watchOS?
  2. Does NECP enforce additional restrictions even with background audio enabled, and how can I address this?

Any guidance or examples of implementing WebSocket audio streaming on watchOS would be greatly appreciated.

Thanks!

TN3135 links to WWDC 2019 Session 716 Streaming Audio on watchOS 6, which is where I go when I want to learn about this stuff.

Share and Enjoy

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

Hey folks! Another watchOS/iOS engineer here

I'm working on a similar use case for an audio streaming and transcribing use case for the Apple Watch.

I've worked through TN3135 as well as WWDC 2019 Session 716 and have the following elements requested turned on

  1. I have an audio background mode set up

  2. I set up the web socket after setting an AudioSession to active

  3. I set request.networkServiceType to .avStreaming

  4. my use case is squarely a audioStreaming use case

I still run into a network error where it says "The Internet connection appears to be offline"

This all said – it seems that there are watch only apps that have figured out how to use web sockets so it seems as though I'm missing something.

https://apps.apple.com/us/app/iris-voicegpt-for-apple-watch/id6737017937

Are there other settings that need to be turned on for this to work?

Someone pinged me about this thread in a different context. Sorry I missed it at the time. IIRC I was out of the office.

I set request.networkServiceType to .avStreaming

This suggests you’re using URLSessionWebSocketTask, which is not something I recommend. Hmmmm, I don’t actually recommend it in any context [1], but you should specifically avoid it on watchOS because the URLSession implementation on watchOS is very different than the implementation on any other Apple platform (on watchOS every session is kinda like a background session, where the actual work is done out of process).

Rather, you should you should use Network framework’s WebSocket support. If you’re using the latest Network framework API, setting that up is trivial. There are some snippets in TN3213 Moving from Multipeer Connectivity to Network framework. If you’re using the C API or the older Swift API, check out this and this, respectively.

I suggest that you prototype that code on macOS, just to make sure the basics work. Then, if you continue to have problems on the watch, reply back here and I’ll dig deeper.

Share and Enjoy

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

[1] See TN3151 Choosing the right networking API.

Hi Quinn!

Thanks for this update. I've published my demo project to https://github.com/leptos-null/WatchOS-WebSocket which uses NWConnection.

I'm still having the same issues. I've included logs in the repo and I've copied that section here:

Logs

macOS:

Launching on arm64, Version 26.5.2 (Build 25F84)
Connecting to wss://echo.websocket.org
Preparing connection
WebSocket opened
Received 32 bytes (text)

watchOS:

Launching on Watch7,9, Version 26.6 (Build 23U67)
Activating audio session to unlock low-level networking
Audio session active; route outputs: ["Speaker"]
Connecting to wss://echo.websocket.org
nw_endpoint_flow_failed_with_error [C1 echo.websocket.org:443 waiting parent-flow (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6, proxy)] already failing, returning
Connection waiting: POSIXErrorCode(rawValue: 50): Network is down
Preparing connection
Connection waiting: POSIXErrorCode(rawValue: 50): Network is down

So I tried this again here in my office and things are working as I expected (using a standalone app on watchOS 26.6). The networking side of this is trivial. All the complications are related to the audio session. Sadly, that’s an area of the system that I’m not an expert in.

The interesting thing here is that, when I start my audio session, watchOS presents its Connect a Device UI. I satisfy that by donning and then choosing my AirPods, and that’s sufficient to get the audio session going, and hence the network going.

I took a look at my audio session code and it’s quite different from your. Probably the biggest difference is that I use the activate(options:completionHandler:) method, which gives me an error if the activation fails.

Share and Enjoy

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

Configuring WebSocket API for watchOS App
 
 
Q