ios - NWEndPoint:从另一个VC获取网关IP地址时返回nil
问题描述
我已经找到了这个问题的解决方案,请参见下面的答案。
我定义了一个函数getGatewayInfo()
来获取网关 IP 地址并将其返回给调用者。print(NetworkUtility().getGatewayInfo())
但是当我从其他 VC调用这个函数时viewDidLoad
,它返回 nil。
从日志中,我可以看到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!"
}
}
}
解决方案
这里的问题是 path in 中的 handler 代码(闭包)monitor.pathUpdateHandler
是异步执行的,所以前面代码中的 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
}
}
}
推荐阅读
- javascript - 如何在反应中将状态从子组件传递到父组件
- c# - 单击其他按钮时如何使按钮不可见
- r - R - 重命名列标题中匹配字符串右侧的所有列标题
- perl - 每个脚本在哈希哈希的 ~7200 次交互处挂起
- python - 为什么我不能在网站上显示我转换的视频?
- html - 点击后如何保持颜色
- java - 如何编写 MediaItem 类型的对象以键入 book
- ruby-on-rails - 如何在 ruby 或 rails 中正确使用 use Noty
- assembly - 简单指令编码
- javascript - 如何在每个路由上注入一个唯一键到一个公共函数而不在节点 js 中传递一个参数