open class ServerTrustPolicyManager {
public let policies: [String: ServerTrustPolicy]
public init(policies: [String: ServerTrustPolicy]) {
self.policies = policies
}
open func serverTrustPolicy(forHost host: String) -> ServerTrustPolicy? {
return policies[host]
}
}
初始化了一个
policies
字典,
key
为
host
,值为选择的响应的策略
初始化方法中设置安全策略及
ServerTrustPolicy
通过
serverTrustPolicy
方法通过host获取
ServerTrustPolicy
对象
不要问为什么分离一个
manager
来管理
ServerTrustPolicy
,不直接使用,因为这是大厂分工要明确,责任到每一层。
1、ServerTrustPolicy
ServerTrustPolicy是一个枚举类:
public enum ServerTrustPolicy {
case performDefaultEvaluation(validateHost: Bool)
case performRevokedEvaluation(validateHost: Bool, revocationFlags: CFOptionFlags)
case pinCertificates(certificates: [SecCertificate], validateCertificateChain: Bool, validateHost: Bool)
case pinPublicKeys(publicKeys: [SecKey], validateCertificateChain: Bool, validateHost: Bool)
case disableEvaluation
case customEvaluation((_ serverTrust: SecTrust, _ host: String) -> Bool)
//代码省略若干
}
public enum NetworkReachabilityStatus {
case unknown
case notReachable
case reachable(ConnectionType)
}
public enum ConnectionType {
case ethernetOrWiFi
case wwan
}
使用:
let networkManager = NetworkReachabilityManager(host: "www.yahibo.top")
networkManager?.listener = { status in
switch status {
case .unknown:
print("未知网络")
break
case .notReachable:
print("这是一个不可达网络")
break
case .reachable(.ethernetOrWiFi):
print("这是一个WiFi网络")
break
case .reachable(.wwan):
print("这是一个蜂窝网络")
break
}
networkManager?.startListening()
注意对象需要声明为全局,在作用域中声明会被销毁
大同小异,编码方式变的更简洁了,这也符合
swift
的编码风格。以上可以看出在
Alamofire
中的网络监测将
WiFi
网络和蜂窝网络归为一类。下面看一下源码。
1、属性
1️⃣、声明一个闭包,在外部实现呢,网络变化时掉用闭包传值
public typealias Listener = (NetworkReachabilityStatus) -> Void
2️⃣、网络是否可达,包括蜂窝和WiFi网络
3️⃣、蜂窝网络是否为可达的
4️⃣、通过WiFi连接网络
5️⃣、获取网络类型
open var networkReachabilityStatus: NetworkReachabilityStatus {
guard let flags = self.flags else { return .unknown }
return networkReachabilityStatusForFlags(flags)
}
6️⃣、设置监听闭包在哪个队列中调用你,默认给主队列
open var listenerQueue: DispatchQueue = DispatchQueue.main
7️⃣、定一个闭包类型的监听属性
初始化
public convenience init?(host: String) {
guard let reachability = SCNetworkReachabilityCreateWithName(nil, host) else { return nil }
self.init(reachability: reachability)
}
private init(reachability: SCNetworkReachability) {
self.reachability = reachability
// Set the previous flags to an unreserved value to represent unknown status
self.previousFlags = SCNetworkReachabilityFlags(rawValue: 1 << 30)
}
存储对象,并获取网络可达标识
到此好像就已经初始化完成
2、启动监听网络
networkManager?.startListening()
内部实现:
open func startListening() -> Bool {
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
context.info = Unmanaged.passUnretained(self).toOpaque()
let callbackEnabled = SCNetworkReachabilitySetCallback(
reachability,
{ (_, flags, info) in
let reachability = Unmanaged<NetworkReachabilityManager>.fromOpaque(info!).takeUnretainedValue()
reachability.notifyListener(flags)
},
&context
)
let queueEnabled = SCNetworkReachabilitySetDispatchQueue(reachability, listenerQueue)
listenerQueue.async {
guard let flags = self.flags else { return }
self.notifyListener(flags)
}
return callbackEnabled && queueEnabled
}