Reachability&SSID在swift中的使用

Reachability.swift


在需要获取手机网络连接方式的时候,Reachability库是一个很好的工具。它可以判断当前网络状态是

  • Wi-Fi(wifi)
  • 蜂窝移动(cellular)
  • 没有连接(none和unavailable,据说在之后的版本中会取消none)

并且在github的不断更新中,现在的Reachability.swift已经支持了swift5.0,并且可以通过swift package manager导入项目中。

官方给的文档中使用方式已经介绍的很清晰了,同时也可以自己稍加改变结合swiftUI或Combine使用。官方给的代码是:

  1. 在闭包中使用:
let reachability = try! Reachability()

reachability.whenReachable = { reachability in
    if reachability.connection == .wifi {
        print("Reachable via WiFi")
    } else {
        print("Reachable via Cellular")
    }
}
reachability.whenUnreachable = { _ in
    print("Not reachable")
}

do {
    try reachability.startNotifier()
} catch {
    print("Unable to start notifier")
}
  1. 在自定义类或结构体中使用(主队列):
let reachability = try! Reachability()

//添加观察者的语句,可以封装在方法中

     NotificationCenter.default.addObserver(self, selector: #selector(reachabilityChanged(note:)), name: .reachabilityChanged, object: reachability)
    do{
      try reachability.startNotifier()
    }catch{
      print("could not start reachability notifier")
    }
//发布通知的代码,广播
@objc func reachabilityChanged(note: Notification) {

  let reachability = note.object as! Reachability

  switch reachability.connection {
  case .wifi:
      print("Reachable via WiFi")
  case .cellular:
      print("Reachable via Cellular")
  case .unavailable:
    print("Network not reachable")
  }
}
//移除观察者的语句,同时停止发布通知
reachability.stopNotifier()
NotificationCenter.default.removeObserver(self, name: .reachabilityChanged, object: reachability)

wifi SSID


在使用时,与获取网络状态相关的功能就是读取Wi-Fi状态下的Wi-Fi信息。SSID(service set identifier)服务集标识符,一般可以当作局域网的名称。同样在github上有一个项目是可以实现获取Wi-Fi info的,对于iOS13及以下都支持。下面截取一个常用的方法:

import Foundation
import SystemConfiguration.CaptiveNetwork

func getSSID() -> String? {
    var ssid: String?
    if let interfaces = CNCopySupportedInterfaces() as NSArray? {
        for interface in interfaces {
//这里的 as! 强制类型转换是可以成功的
            if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as! CFString) as NSDictionary? {
                ssid = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String
                break
            }
        }
    }
    return ssid
}

注意


在使用时也需要根据项目的要求对上面的信息做一些改变,比如let reachability = try! Reachability()这个初始化语句,使用了强制try,应谨慎表达式抛出错误,引发运行时错误。我的方法是:

  • 改为 try?忽略错误,同时在后面reachability的调用中使用可选链
  • 改为try,使用do-catch语句包围。

特别是如果使用了Future这样的publisher,就要格外注意初始化的成败。如果初始化失败future不会发出任何消息,但是在项目的程序调用中一般是认为future是会发出消息的,这样可能会在之后的调用中产生问题。所以要在初始化时就增加判断机制,失败时抛错并return。

此外在写工程代码时要注意避免“不优雅”的多层嵌套。衡量代码好坏的一个重要标准是代码的“深度”,即嵌套层数。多层嵌套降低代码的可读性,同时也会消耗内存资源。因为执行程序其实就是内存的入栈出栈,过分嵌套可能导致爆栈(可以理解为俄罗斯套娃,套得越深取出来的步骤就越复杂,也更耗时)。

以上,在写完代码后要二次检查:

  • 功能能否正常实现
  • 常变量、方法的命名是否规范
  • 代码的判断机制和错误处理机制是否合乎逻辑,不累赘丑陋
  • 注释是否规范,特别是对复杂语句要有必要的注释(比如try! as!的使用要写明白为什么会确保不出问题)

完成以上内容之后,根据工作的性质按照commit规范提交。
乌拉!


2020.2.26更新记录一下
在使用combine的时候没有注意引用持有,reachability在调用完成之后就被销毁了,使用Future发布不了任何值。最可怕的是我找bug找了一下午也没看出来是引用持有发生了问题(真菜啊),所以还要复习一下属性的生命周期。之前学的时候没有实际体会,现在有了实际体会又不会用了(逃
重要的是功能代码一定要自己测试测试测试!重要的事情说三遍!debug preview的模式就可以


2.27记录
whenReachable 和 whenUnreachable这两个闭包使用的时候要注意,他们是在网络状态发生改变的时候才会发出值的,在使用combine结合项目的时候最好看一起reachability的源码,获取网络的状态可以直接通过实例化Reachability之后访问connnection属性拿到。

你可能感兴趣的:(Reachability&SSID在swift中的使用)