如何在Swift中检测iOS设备是否使用wifi连接?



在一个旧的,基于Objective-C的项目中,我一直在使用下面的代码来检测iOS设备当前是否使用Wifi(不是蜂窝)连接。

由于Objective-C的指针,我试图将这段代码翻译成Swift 5失败了。在Swift中是否有一个干净的方法来使用这个解决方案?

或者现在有更好的方法来解决这个问题吗?我找到了使用Swift或NWPathMonitor()的可达性端口的解决方案。虽然它们似乎在一般情况下工作,但这些解决方案用于监视连接状态并发送更改通知,而不(很好地)支持一次性检查。 事件虽然这些解决方案可以用来获取当前

连接状态,这是使用委托回调方法或闭包完成的。因此,不可能在现有的代码中使用这些解决方案,这些代码是为了"同步"工作而创建的。(没有回调/闭包)。是否有一种简单的方法在Swift中使用localWiFiAvailable?

代码:

+ (BOOL)localWiFiAvailable {
struct ifaddrs *addresses;
struct ifaddrs *cursor;
BOOL wiFiAvailable = NO;
if (getifaddrs(&addresses) != 0) return NO;

cursor = addresses;
while (cursor != NULL) {
if ((cursor -> ifa_addr -> sa_family == AF_INET) && !(cursor -> ifa_flags & IFF_LOOPBACK)) { // Ignore the loopback address
// Check for WiFi adapter
#if TARGET_IPHONE_SIMULATOR
wiFiAvailable = true;
break;
#else
if (strcmp(cursor -> ifa_name, "en0") == 0) {
wiFiAvailable = YES;
break;
}
#endif
}
cursor = cursor -> ifa_next;
}

freeifaddrs(addresses);
return wiFiAvailable;
}   

NWPathMonitor()不能使用的详细信息:

正如@baronfac在他的评论中指出的,NWPathMonitor()也可以传递电流状态,但这只能使用.pathUpdateHandler闭包来完成。

我正在使用第三方库,我可以覆盖souldSendData() -> Bool方法。不允许在移动连接上发送数据,只能在WiFi上发送数据。这些方法需要立即决定返回真或假。因此,等待闭包是不可能的。

因此,我在这里受到现有类的限制。是的,连接随时都可能改变,但这是另一个问题。例如,NWPathMonitor可用于在连接更改为移动时取消传输。

使用上面的代码在objective - c中解决这个问题是没有问题的。问题很简单,如果这样的"直接"解决方案在Swift中也是可能的。虽然在Swift项目中使用objective - c代码是可能的,但我更愿意保持项目仅Swift。

如Paulw11所述,推荐的方法是使用NWPathMonitor。一个常见的做法是在UIViewController类中:

private var monitor: NWPathMonitor? 
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
monitor = NWPathMonitor()
monitor?.pathUpdateHandler = { [weak self] path in
if !path.isExpensive { // this means the device is connected via WiFi
// enter your code here
}
}
let queue = DispatchQueue(label: "Monitor")
monitor?.start(queue: queue)    // start to monitor the connection
}
override func viewWillDisappear(_ animated: Bool) {
monitor?.cancel()    // end to monitor the connection 
super.viewWillDisappear(animated)
}

编辑:

感谢FLichter和Rob Napier的澄清。也许使用这种方法会有所帮助:

func shouldSendData() -> Bool {
let monitor = NWPathMonitor()
return !monitor.currentPath.isExpense
}

最新更新