TN3135: Low-level networking on watchOS
Learn about the supported use cases for low-level networking on watchOS.
Overview
watchOS groups networking into two categories:
High-level networking. This includes the HTTP and HTTPS support in URLSession, and any code layered on top of that.
Low-level networking. This includes Network framework, Stream, and any other API that runs a TCP connection or UDP session directly. That includes the low-level aspects of URLSession, namely URLSessionStreamTask and URLSessionWebSocketTask. It also includes APIs, like NWBrowser and NetService, that interact directly with Bonjour.
watchOS allows all apps to use high-level networking equally. However, it only allows an app to use low-level networking under specific circumstances:
It allows an audio streaming app to use low-level networking while actively streaming audio. Support for this was introduced in watchOS 6.
It allows a VoIP app to use low-level networking while running a call using CallKit. Support for this was added in watchOS 9.
It allows an app on watchOS to set up an application service listener so that the same app on tvOS can establish a low-level connection to it using the DeviceDiscoveryUI framework. Support for this was added in watchOS 9 and tvOS 16.
watchOS blocks low-level networking outside of these specific circumstances. For example, if a normal app attempts to start an NWConnection, that connection will stay in the NWConnection.State.waiting(_:) state with an error of ENETDOWN. Similarly, an NWPathMonitor will remain in the NWPath.Status.unsatisfied state.
The BSD sockets API doesn’t work for networking on watchOS under any circumstances. Use Network framework instead.
Foundation has various APIs for synchronously creating a value using bytes loaded from a URL. For example, creates a data value in this way. Using these APIs with network URLs is not best practice on any Apple platform and is not supported by watchOS. Instead, load network URLs with a dedicated asynchronous networking API, like URLSession.
When writing watchOS networking code, test it on a real device; the simulator always allows low-level networking.
Also, 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.
For more information about building an audio streaming app for watchOS, see WWDC 2019 Session 716 Streaming Audio on watchOS 6.
Revision History
2024-02-27 Fixed a typo.
2022-10-18 Added a discussion of the DeviceDiscoveryUI framework.
2022-09-27 Republished as TN3135. Updated with information about watchOS 9. Made significant editorial changes.
2021-05-14 Updated to call out that URLSessionStreamTask and URLSessionWebSocketTask are considered low-level networking.
2019-12-18 First published as “Low-Level Networking on watchOS” on Apple Developer Forums.
See Also
Latest
TN3205: Low-latency communication with RDMA over ThunderboltTN3206: Updating Apple Pay certificatesTN3179: Understanding local network privacyTN3190: USB audio device design considerationsTN3194: Handling account deletions and revoking tokens for Sign in with AppleTN3193: Managing the on-device foundation model’s context windowTN3115: Bluetooth State Restoration app relaunch rulesTN3192: Migrating your iPad app from the deprecated UIRequiresFullScreen keyTN3151: Choosing the right networking APITN3111: iOS Wi-Fi API overviewTN3191: IMAP extensions supported by Mail for iOS, iPadOS, and visionOSTN3134: Network Extension provider deploymentTN3189: Managing Mail background traffic loadTN3187: Migrating to the UIKit scene-based life cycleTN3188: Troubleshooting In-App Purchases availability in the App Store