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.pathUpdateHandler
path 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
}
}
}