NWConnection is crashed on iOS 15 and 16, but it works well on 17

Hello 👋

I need to implement a logic for searching for devices with our own service type using Bonjour. Using the NWBrowser, I can receive a list of all devices and connect to them. I need to utilize a WebSocket connection. By the property endpoint of NWBrowser.Result objects I can create NWConnection. Below is my implementation which works fine on iOS 17:

let params = NWParameters.tcp
        let webSocketOptions = NWProtocolWebSocket.Options()
        params.defaultProtocolStack.applicationProtocols.insert(webSocketOptions, at: 0)

        // The `endpoint` is from `browseResultsChangedHandler` of NWBrowser
        let connection = NWConnection(to: endpoint, using: params)

However, it doesn't work on iOS 15 and 16 because of the crash:

2024-06-01 16:07:18.136068+0300 MyApp[591:16845549] [] nw_endpoint_get_url called with null endpoint
2024-06-01 16:07:18.136932+0300 MyApp[591:16845549] [] nw_endpoint_get_url called with null endpoint, dumping backtrace:
        [arm64] libnetcore-3100.102.1
    0   Network                             0x000000018530e174 __nw_create_backtrace_string + 188
    1   Network                             0x000000018538ba20 nw_endpoint_get_url + 852
    2   Network                             0x0000000185310020 nw_ws_create_client_request + 84
    3   Network                             0x0000000184f4b3cc __nw_ws_create_state_block_invoke + 416
    4   Network                             0x000000018504bc68 nw_protocol_options_access_handle + 92
    5   Network                             0x0000000184f41e98 nw_ws_create_state + 204
    6   Network                             0x0000000184f41aec __nw_protocol_copy_ws_definition_block_invoke_2 + 176
    7   Network                             0x0000000184f69188 nw_framer_protocol_connected + 348
    8   Network                             0x00000001854a6638 _ZL29nw_socket_handle_socket_eventP9nw_socket + 1560
    9   libdispatch.dylib                   0x0000000126b89d50 _dispatch_client_callout + 16
    10  libdispatch.dylib                   0x0000000126b8d208 _dispatch_continuation_pop + 756
    11  libdispatch.dylib                   0x0000000126ba48d4 _dispatch_source_invoke + 1676
    12  libdispatch.dylib                   0x0000000126b94398 _dispatch_workloop_invoke + 2428
    13  libdispatch.dylib                   0x0000000126ba0b74 _dispatch_workloop_worker_thread + 1716
    14  libsystem_pthread.dylib             0x000000012371f814 _pthread_wqthread + 284
    15  libsystem_pthread.dylib             0x000000012371e5d4 start_wqthread + 8

Also, there is the stack trace of bt-command in the debug console:

* thread #20, queue = 'com.apple.network.connections', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000123078c24 libsystem_platform.dylib`_platform_strlen + 4
    frame #1: 0x00000001803c538c CoreFoundation`CFStringCreateWithCString + 40
    frame #2: 0x0000000185310030 Network`nw_ws_create_client_request + 100
    frame #3: 0x0000000184f4b3cc Network`__nw_ws_create_state_block_invoke + 416
    frame #4: 0x000000018504bc68 Network`nw_protocol_options_access_handle + 92
    frame #5: 0x0000000184f41e98 Network`nw_ws_create_state + 204
    frame #6: 0x0000000184f41aec Network`__nw_protocol_copy_ws_definition_block_invoke_2 + 176
    frame #7: 0x0000000184f69188 Network`nw_framer_protocol_connected + 348
    frame #8: 0x00000001854a6638 Network`nw_socket_handle_socket_event(nw_socket*) + 1560
    frame #9: 0x0000000126b89d50 libdispatch.dylib`_dispatch_client_callout + 16
    frame #10: 0x0000000126b8d208 libdispatch.dylib`_dispatch_continuation_pop + 756
    frame #11: 0x0000000126ba48d4 libdispatch.dylib`_dispatch_source_invoke + 1676
    frame #12: 0x0000000126b94398 libdispatch.dylib`_dispatch_workloop_invoke + 2428
    frame #13: 0x0000000126ba0b74 libdispatch.dylib`_dispatch_workloop_worker_thread + 1716
    frame #14: 0x000000012371f814 libsystem_pthread.dylib`_pthread_wqthread + 284

I have found out a couple things:

  1. There are no crashes if I initialize the NWConnection object with using, for instance, the NWEndpoint.url(_:). initializer:
let urlHost = URL(string: "ws://10.20.30.40:5060")!
        let endpoint = NWEndpoint.url(urlHost)

        let params = NWParameters.tcp
        let webSocketOptions = NWProtocolWebSocket.Options()
        params.defaultProtocolStack.applicationProtocols.insert(webSocketOptions, at: 0)

        let connection = NWConnection(to: endpoint, using: params)
        self.connection = connection

But, in this case, I must extract IP-addresses 🙇‍♂️ Meanwhile, there is a topic such as Don’t Try to Get the Device’s IP Address..

  1. I have tried to find anything that could help me move forward in this problem and run into some odd behaviour. There is a property skipHandshake of NWProtocolWebSocket.Options object. If I set the property value to true, there are no crashes as well as no connection to a device.
NWConnection is crashed on iOS 15 and 16, but it works well on 17
 
 
Q