Files
simplex-chat/apps/ios/Shared/Model/NetworkObserver.swift
T
Narasimha-sc 7749ebb66b android, ios: pass the chat controller to the network info command
The controller was read twice - checked and then read again inside the command -
so replacing it between the two failed the command, and on iOS reading it again
terminates the app, as getChatCtrl() is a fatalError when it is not set. It is
now read once and passed to the command.

A failed report is not alerted about, as the network info is reported
automatically: the command is sent with sendCmd rather than sendCommandOkResp,
which shows an alert.
2026-10-05 09:33:06 +00:00

75 lines
2.3 KiB
Swift

//
// NetworkObserver.swift
// SimpleX (iOS)
//
// Created by Avently on 05.04.2024.
// Copyright © 2024 SimpleX Chat. All rights reserved.
//
import Foundation
import Network
import SimpleXChat
class NetworkObserver {
static let shared = NetworkObserver()
private let queue: DispatchQueue = DispatchQueue(label: "chat.simplex.app.NetworkObserver")
private var prevInfo: UserNetworkInfo? = nil
private var monitor: NWPathMonitor?
private let monitorLock: DispatchQueue = DispatchQueue(label: "chat.simplex.app.monitorLock")
func restartMonitor() {
monitorLock.sync {
monitor?.cancel()
let mon = NWPathMonitor()
mon.pathUpdateHandler = { [weak self] path in
self?.networkPathChanged(path: path)
}
mon.start(queue: queue)
monitor = mon
}
}
private func networkPathChanged(path: NWPath) {
let info = UserNetworkInfo(
networkType: networkTypeFromPath(path),
online: path.status == .satisfied
)
if (prevInfo != info) {
prevInfo = info
setNetworkInfo(info)
}
}
private func networkTypeFromPath(_ path: NWPath) -> UserNetworkType {
if path.usesInterfaceType(.wiredEthernet) {
.ethernet
} else if path.usesInterfaceType(.wifi) {
.wifi
} else if path.usesInterfaceType(.cellular) {
.cellular
} else if path.usesInterfaceType(.other) {
.other
} else {
.none
}
}
private static var networkObserver: NetworkObserver? = nil
private func setNetworkInfo(_ info: UserNetworkInfo) {
logger.debug("setNetworkInfo Network changed: \(String(describing: info))")
DispatchQueue.main.sync {
ChatModel.shared.networkInfo = info
}
self.monitorLock.sync {
guard let ctrl = currentChatCtrl() else { return }
do {
// the controller is passed, so that resetting it while the report is sent is not a crash
try apiSetNetworkInfo(info, ctrl: ctrl)
} catch let err {
logger.error("setNetworkInfo error: \(responseError(err))")
}
}
}
}