NWEndPoint:当从另一个 VC 获取网关的 IP 地址时,它 returns 为零
NWEndPoint: it returns nil when getting gateway's IP address from another VC
我找到了这个问题的答案,请看下面的答案。
我定义了一个函数 getGatewayInfo()
来获取网关 IP 地址并将其 return 发送给调用者。
但是当我从其他 VC 的 viewDidLoad
调用这个 func print(NetworkUtility().getGatewayInfo())
时,它 returns nil.
从日志中,我可以看到 gatewayIPAddress
已经从 NWEndpoint
获得了值,即 192.168.1.1
。但是,它 returns 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!"
}
}
}
这里的问题是monitor.pathUpdateHandler
路径中的处理程序代码(闭包)是异步执行的,所以前面代码中的return语句会先于它执行。最终,returned 参数为 nil
.
而且因为我们不知道闭包中的代码何时会像某些网络请求一样完成。所以我们不能在这个函数中使用 return 方法。相反,我们应该使用另一个完成处理程序来 return 参数值,即回调。就像我们在某些 JSON 请求函数中所做的那样。
代码涉及另一个completionHandler
以防return字符串参数:
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
}
}
}
我找到了这个问题的答案,请看下面的答案。
我定义了一个函数 getGatewayInfo()
来获取网关 IP 地址并将其 return 发送给调用者。
但是当我从其他 VC 的 viewDidLoad
调用这个 func print(NetworkUtility().getGatewayInfo())
时,它 returns nil.
从日志中,我可以看到 gatewayIPAddress
已经从 NWEndpoint
获得了值,即 192.168.1.1
。但是,它 returns 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!"
}
}
}
这里的问题是monitor.pathUpdateHandler
路径中的处理程序代码(闭包)是异步执行的,所以前面代码中的return语句会先于它执行。最终,returned 参数为 nil
.
而且因为我们不知道闭包中的代码何时会像某些网络请求一样完成。所以我们不能在这个函数中使用 return 方法。相反,我们应该使用另一个完成处理程序来 return 参数值,即回调。就像我们在某些 JSON 请求函数中所做的那样。
代码涉及另一个completionHandler
以防return字符串参数:
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
}
}
}