I'm working on a Swift app where I need to know when the device is connected to the internet or not and I implemented the following code to do that.
import Foundation
import Network
class NetworkMonitor: ObservableObject{
static let shared = NetworkMonitor()
private let queue = DispatchQueue.global()
private let monitor: NWPathMonitor
public private(set)var isConnected :Bool=false
public private(set)var connectionType :ConnectionType = .unknown
enum ConnectionType{
case wifi
case cellular
case unknown
}
init(){
monitor = NWPathMonitor()
}
public func startMonitoring(){
monitor.pathUpdateHandler={[weak self] path in
self?.isConnected=path.status == .satisfied
self?.getConnectionType(path)
}
monitor.start(queue: queue)
}
public func stopMonitoring(){
monitor.cancel()
}
public func getConnectionType(_ path: NWPath){
if(path.usesInterfaceType(.wifi)){
connectionType = .wifi
}else if(path.usesInterfaceType(.cellular)){
connectionType = .cellular
}else{
connectionType = .unknown
}
}
}
The problem arises when the function startMonitoring() is called. Everything seems to work fine but I get this error messages in the console
2022-12-01 13:04:37.327650+0100 Luuk[11692:1287784] [] nw_path_evaluator_set_queue Client error: set queue after starting
2022-12-01 13:04:37.328799+0100 Luuk[11692:1287784] [] nw_path_evaluator_set_queue Client error: set queue after starting, dumping backtrace:
[arm64] libnetcore-2750.120.19.0.1
0 libnetwork.dylib 0x0000000181950d4c __nw_create_backtrace_string + 192
1 libnetwork.dylib 0x0000000181166f70 nw_path_evaluator_set_queue + 304
2 libnetwork.dylib 0x00000001811841f8 nw_path_monitor_set_queue + 96
3 libswiftNetwork.dylib 0x00000001f0846ee4 $s7Network13NWPathMonitorC5start5queueySo012OS_dispatch_E0C_tF + 72
4 Luuk 0x0000000104cfa418 $s4Luuk14NetworkMonitorC15startMonitoringyyF + 216
5 Luuk 0x0000000104c7d010 $s4Luuk11SummaryViewV4bodyQrvgyycfU1_yyScMYccfU_ + 56
6 Luuk 0x0000000104c137e0 $sIeg_IeyB_TR + 48
7 libdispatch.dylib 0x0000000105640c70 _dispatch_call_block_and_release + 32
8 libdispatch.dylib 0x00000001056427c0 _dispatch_client_callout + 20
9 libdispatch.dylib 0x0000000105652c68 _dispatch_main_queue_drain + 1204
10 libdispatch.dylib 0x00000001056527a4 _dispatch_main_queue_callback_4CF + 44
11 CoreFoundation 0x00000001803fe800 5198FB57-5645-3B34-A49F-F32B52256CF3 + 333824
12 CoreFoundation 0x00000001803b8704 5198FB57-5645-3B34-A49F-F32B52256CF3 + 46852
13 CoreFoundation 0x00000001803cbbc8 CFRunLoopRunSpecific + 600
14 GraphicsServices 0x000000019c4ff374 GSEventRunModal + 164
15 UIKitCore 0x0000000182d3b648 3ED35565-456D-33CB-B554-6C567FA81585 + 5326408
16 UIKitCore 0x0000000182abcd90 UIApplicationMain + 364
17 SwiftUI 0x000000018821df24 5B6954AE-CE76-34AC-90F9-F7A8DEE0910F + 2359076
18 SwiftUI 0x000000018814be08 5B6954AE-CE76-34AC-90F9-F7A8DEE0910F + 1498632
19 SwiftUI 0x000000018812d0f4 $s7SwiftUI3AppPAAE4mainyyFZ + 128
20 Luuk 0x0000000104ce5318 $s4Luuk0A3AppV5$mainyyFZ + 40
21 Luuk 0x0000000104ce53c0 main + 12
22 dyld 0x000000010540dce4 start + 520
I searched online but there's not a lot of information about this kind of error. Any help would be much appreciated.
When I comment out the line
monitor.start(queue: queue)
the error goes away
That error could be provoked by the repeated use of the same instance of NWPathMonitor after it is cancelled -as described here-.
When an instance of NWPathMonitor is cancelled, you can't use start() again. The only way would be to create a new instance.
Can you check in your code if you are trying to cancel->start with the same instance?
Also, I'd say you should maybe change the queue in which you are setting the start(), instead of global, you could set up one specific for this purpose
or even use the main thread.