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:
- 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..
- 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.