NWEndPoint: возвращает ноль при получении IP-адреса шлюза от другого виртуального канала.

Я нашел решение этого вопроса, см. Ответ ниже.

Я определяю функцию getGatewayInfo()чтобы получить IP-адрес шлюза и вернуть его вызывающему абоненту. Но когда я называю это функцией print(NetworkUtility().getGatewayInfo()) от других венчурных капиталистов viewDidLoad, он возвращает ноль.

Из журнала я мог видеть gatewayIPAddress получил ценность от NWEndpoint, который 192.168.1.1. Однако он возвращает nil и выводит "IP-адрес шлюза не найден!". Не могли бы вы намекнуть, где я сделал не так?

Gateway IP address is not found!
Gateway: 192.168.1.1
import UIKit
import Network

class NetworkUtility {
    var gatewayIPAddress: String?
    
    func getGatewayInfo() -> String {
        let monitor = NWPathMonitor(requiredInterfaceType: .wifi)
        monitor.pathUpdateHandler = { path in
            let endpoint = path.gateways[0]
            
            switch endpoint {
            case .hostPort(let host, _):
                self.gatewayIPAddress = host.debugDescription
                print("Gateway: \(self.gatewayIPAddress!)")
            default:
                break
            }
        }
        monitor.start(queue: DispatchQueue(label: "nwpathmonitor.queue"))
        
        if let gatewayIPAddress = gatewayIPAddress {
            return gatewayIPAddress
        } else {
            return "Gateway IP address is not found!"
        }
    }
}

1 ответ

Решение

Проблема здесь в коде обработчика (закрытие) в monitor.pathUpdateHandlerpath in выполняется асинхронно, поэтому оператор return в предыдущем коде будет выполнен перед ним. В конце концов, возвращаемый параметр nil.

И поскольку мы не знаем, когда код в закрытии будет завершен, как какой-то сетевой запрос. Таким образом, мы не можем использовать метод возврата в этой функции. Вместо этого мы должны использовать другой обработчик завершения, чтобы вернуть значение параметра, которым является обратный вызов. Как то, что мы делаем в некоторых функциях запросов JSON.

Код для вовлечения другого completionHandler в случае возврата строкового параметра:

func getGatewayInfo(completionHandler: @escaping (String) -> ()) {
    let monitor = NWPathMonitor(requiredInterfaceType: .wifi)
    monitor.pathUpdateHandler = { path in
        if let endpoint = path.gateways.first {
            switch endpoint {
            case .hostPort(let host, _):
                let remoteHost = host.debugDescription
                print("Gateway: \(remoteHost)")
                // Use callback here to return the ip address to the caller
                completionHandler(remoteHost)
            default:
                break
            }
        } else {
            print("Wifi connection may be dropped.")
        }
    }
    monitor.start(queue: DispatchQueue(label: "nwpathmonitor.queue"))
}

Звонящий:

override func viewDidLoad() {
    super.viewDidLoad()
    title = pageTitle
    
    // Receive remoteHost from callback parameter(aka. gateway ip address)
    NetworkUtility().getGatewayInfo { (remoteHost) in
        print("remote: \(remoteHost)")
        DispatchQueue.main.async {
            self.gwIPAddress.text = remoteHost
        }
    }
}
Другие вопросы по тегам