watchOS 9: Error getting network data status Error Domain=NSPOSIXErrorDomain Code=19 "Operation not supported by device"

I have an app that stopped working properly on watchOS 9, although it works perfectly fine on simulators.

It uses WebSocket on an HTTPS server hosted on DigitalOcean behind an nginx proxy.

The error I receive is "The Internet connection appears to be offline" but that does not make sense as other applications are able to use the internet properly on the device.

Here are logs from Xcode running on device:

2022-09-17 16:22:40.409850-0400 Watch Mirror Watch App[354:11674] Connection 1: received failure notification

2022-09-17 16:22:40.413273-0400 Watch Mirror Watch App[354:11674] Connection 1: failed to connect 1:50, reason -1

2022-09-17 16:22:40.413318-0400 Watch Mirror Watch App[354:11674] Connection 1: encountered error(1:50)

2022-09-17 16:22:40.436009-0400 Watch Mirror Watch App[354:11677] Error getting network data status Error Domain=NSPOSIXErrorDomain Code=19 "Operation not supported by device"

2022-09-17 16:22:40.436497-0400 Watch Mirror Watch App[354:11677] Task <03D663EF-3CD1-4906-9343-C6B9DD112B11>.<1> HTTP load failed, 0/0 bytes (error code: -1009 [1:50])

2022-09-17 16:22:40.449161-0400 Watch Mirror Watch App[354:11678] [] Error while receiving The Internet connection appears to be offline.

2022-09-17 16:22:40.449134-0400 Watch Mirror Watch App[354:11677] Task <03D663EF-3CD1-4906-9343-C6B9DD112B11>.<1> finished with error [-1009] Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={NSErrorFailingURLStringKey=[redacted], NSErrorFailingURLKey=[redacted] NSLocalizedDescription=The Internet connection appears to be offline., _NSURLErrorRelatedURLSessionTaskErrorKey=(

    "LocalWebSocketTask <03D663EF-3CD1-4906-9343-C6B9DD112B11>.<1>"

), _NSURLErrorFailingURLSessionTaskErrorKey=LocalWebSocketTask <03D663EF-3CD1-4906-9343-C6B9DD112B11>.<1>}

Networking should always be tested on device, as simulators use the Mac’s network. Also, sockets can only be used via Network.framework on watchOS, and only for audio streaming. More info here: https://developer.apple.com/videos/play/wwdc2019/716/

Getting the same error with URLSessionWebSocketTask on a real device in watchOS 9

Getting the same error with URLSessionWebSocketTask on a real device in watchOS 9

Right. watchOS’s low-level networking rules apply to all APIs below the HTTP[S] support in URLSession. So, even though URLSessionWebSocketTask is part of URLSession, it’s still a low-level networking API.

Matt called this out in his Low-Level Networking on watchOS post.

The kicker here is that earlier versions of watchOS did not consistently enforce these rules (r. 83682211). In some situations low-level networking would work even when it wasn’t supposed to. That bug has been fixed in watchOS 9.

Share and Enjoy

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

@eskimo thanks for the reply. I see the point, but this is a very big problem: this feature was documented as supported and worked perfectly fine.

This fix has two problems: applications that were published and approved by Apple (which I assumed vetted every SDK API call in the code) are now broken with no easy fix besides implementing polling (my case, which is much worse for the user than a proper WebSockets connection); and the error it reports is completely misleading, instead indicating the device isn’t connected to the internet.

I’ve seen some other evidence of people facing problems with this on libraries such as Firebase, which is used by a lot of companies.

OlympusDev wrote:

This is interesting because Apple listed in their release notes for watchOS 6 that URLSessionWebSocketTask was supported

Right, and that’s correct, but only within the scope of an audio streaming app.


WesleydeSouza wrote:

this feature … worked perfectly fine.

That’s not my experience. This is one of the reasons why there’s been so much confusion about this issue in recent years. The above-mentioned bug means that low-level networking without an audio session would work in some circumstances but not in others. So some folks would write in to DTS and ask “Why isn’t this working?” and other would ask “Why is this working?”

Share and Enjoy

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

I don't think when it worked vs when it didn't is all that complicated. Here is a rough timeline of watchOS versions and my believed status of websockets (outside of audio sessions) on them:

  • watchOS 6: I don't believe websockets worked at all. I remember seeing the release notes saying they were supported, but I tried them and they didn't work. I actually thought it was a bug that they didn't work because the release notes clearly state that URLSessionWebSocketTask is supported and lists no caveats.
  • watchOS 7: I tried websockets again and they worked perfectly. I thought this meant that the bug preventing websockets from working was fixed.
  • watchOS 8: Some version of watchOS 8 broke the ping function of URLSessionWebSocketTask, but NWConnection websockets still worked fine
  • watchOS 9: All websockets stopped working completely

I'm not sure what people were doing that made this confusing unless they were testing across watchOS versions. Even Google has the Firebase Realtime Database package for watchOS that uses websockets, so it's not like just small users got confused. Websockets worked perfectly for at least one year, and mostly fine for at least 2. Also many apps for watchOS that use websockets "incorrectly" apparently got approved for the App Store (Spotify possibly being one of them since their app also broke with watchOS 9).

My big question is WHY are websockets not allowed to be used outside of audio sessions? The use-cases for websockets on watchOS aren't going to magically go away if you say they aren't allowed. How is spamming rest calls instead a better solution?

Even at this very moment the page for URLSessionWebSocketTask says it is supported on watchOS 6+, with no mention of it not working outside of audio streaming: https://developer.apple.com/documentation/foundation/urlsessionwebsockettask

I don't think when it worked vs when it didn't is all that complicated.

Your summary does not cover all the edge cases I’m aware of. I’m not going to post all those details here because a) I just don’t have time to test them all, b) the expected behaviour has always been that described in Matt’s post, and any variance from that is, from Apple’s perspective, a bug.

What I will say is…

When writing watchOS networking code, test your networking code in a wide variety of network environments. Specifically, test it when the paired iPhone is available and when the paired iPhone is not available. The best way to test the latter is to turn off both Wi-Fi and Bluetooth in the Settings app on the iPhone. Do not use Control Center for this. For an explanation of the difference between these two mechanisms, see Use Bluetooth and Wi-Fi in Control Center.

My big question is WHY are websockets not allowed to be used outside of audio sessions?

I can’t answer ‘why’ questions like this.

Even at this very moment the page for URLSessionWebSocketTask says it is supported on watchOS

Well, that’s technically true, but I agree it’s misleading. The one obvious takeaway from this whole business is that we need better documentation about this limitation, and I’m actively working on that effort.

Share and Enjoy

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

Your summary does not cover all the edge cases I’m aware of. I’m not going to post all those details here because a) I just don’t have time to test them all, b) the expected behaviour has always been that described in Matt’s post, and any variance from that is, from Apple’s perspective, a bug.

While I understand why technically this might be undesirable and difficult, from a product perspective Apple has been pushing standalone apps for the Watch now, and some use cases are just impossible without hacks like polling or a companion iPhone app, such as messaging applications.

I was curious if things like Facebook Messenger stopped working but then realized it uses the classic iPhone connection to function.

Is there any alternative besides polling for this kind of need (to be able to receive a message asynchronously), or is the suggestion that this kind of use requires an iPhone application to handle all the network?

Is there any alternative besides polling for this kind of need

Our general advice on that front is to use push notifications. I’m by no means a push notifications expert, but my understanding is that watchOS apps have been able to use them for quite some time now.

Share and Enjoy

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

watchOS 9: Error getting network data status Error Domain=NSPOSIXErrorDomain Code=19 "Operation not supported by device"
 
 
Q