本章节讲解如何使用swift连接网络,实时的监听到网络的状态,在主界面中进行调用,网络包含Wi-Fi 和 蜂窝。
1.封装一个判断是否有网络的类
2.在封装类注册通知
3.主界面接收注册通知,并且调用封装的网络类
4.成功测试,有网络为true,否则false
一:AllExpanded类
import UIKit
import WHToast
import MBProgressHUD
import SystemConfiguration
class AllExpanded{
private var hud:MBProgressHUD?
init() {
startNetworkReachabilityNotifier()
checkInitialNetworkStatus()
}
private func checkInitialNetworkStatus() {
let isReachable = isConnectedToNetwork()
notifyReachabilityChanged(isReachable: isReachable)
}
func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_storage()
zeroAddress.ss_len = __uint8_t(MemoryLayout<sockaddr_storage>.size)
zeroAddress.ss_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) { zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var flags: SCNetworkReachabilityFlags = []
if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
return false
}
let isReachable = flags.contains(.reachable)
let needsConnection = flags.contains(.connectionRequired)
let canConnectAutomatically = flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic)
return isReachable && (!needsConnection || canConnectAutomatically)
}
private func startNetworkReachabilityNotifier() {
var zeroAddress = sockaddr_storage()
zeroAddress.ss_len = __uint8_t(MemoryLayout<sockaddr_storage>.size)
zeroAddress.ss_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) { zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var context = SCNetworkReachabilityContext(
version: 0,
info: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()),
retain: nil,
release: nil,
copyDescription: nil
)
if SCNetworkReachabilitySetCallback(defaultRouteReachability!, { (_, flags, info) in
let reachability = Unmanaged<AllExpanded>.fromOpaque(info!).takeUnretainedValue()
reachability.notifyReachabilityChanged(flags)
}, &context) {
SCNetworkReachabilityScheduleWithRunLoop(defaultRouteReachability!, CFRunLoopGetCurrent(), CFRunLoopMode.defaultMode.rawValue)
}
}
private func notifyReachabilityChanged(isReachable: Bool) {
NotificationCenter.default.post(name: .reachabilityChanged, object: nil, userInfo: ["reachable": isReachable])
}
private func notifyReachabilityChanged(_ flags: SCNetworkReachabilityFlags) {
let isReachable = flags.contains(.reachable) && (!flags.contains(.connectionRequired) || (flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic)))
notifyReachabilityChanged(isReachable: isReachable)
}
}
extension Notification.Name {
static let reachabilityChanged = Notification.Name("reachabilityChanged")
}
二:LoginViewController类
override func viewDidLoad() {
super.viewDidLoad()
//接收注册的通知
NotificationCenter.default.addObserver(self, selector: #selector(handleReachabilityChange(_:)), name: .reachabilityChanged, object: nil)
// Check initial network status
// Check initial network status
let isReachable = allExpanded.isConnectedToNetwork()
handleReachabilityChange(Notification(name: .reachabilityChanged, object: nil, userInfo: ["reachable": isReachable]))
}
deinit {
// Remove observer when the view controller is deinitialized
NotificationCenter.default.removeObserver(self, name: .reachabilityChanged, object: nil)
}
@objc private func handleReachabilityChange(_ notification: Notification) {
if let userInfo = notification.userInfo, let isReachable = userInfo["reachable"] as? Bool {
//显示与隐藏红色的提示框(没有网络)
if isReachable {
loginView.netWorkVm.isHidden = true
} else {
loginView.netWorkVm.isHidden = false
}
}
}
至此就阐述完毕,功能测试成功,运行到手机上,切换网络可实时的监听打印到数据信息;