Quản lý kết nối mạng với swift
Nếu đã từng dùng thư viện bên thứ ba như Reachability hay Alamofire để quản lý kết nối mạng thì kể từ iOS 12 bạn đã có thể làm điều này trực tiếp với Network
framework .
NWPathMonitor
NWPathMonitor
là class cung cấp khả năng quan sát và xử lý trạng thái khi tình trạng mạng thay đổi. Mỗi khi có connection update, NWPathMonitor
sẽ kích hoạt closure pathUpdateHandler
với input là NWPath
- object chứa các thông tin về connection hiện giờ như status mạng, protocol được support (IPv4, IPv6), connection type (wifi, dữ liệu di động, …). Để bắt đầu quan sát, ta chỉ cần gán pathUpdateHandler
và gọi function start(queue:)
với queue chạy closure.
Cần lưu ý rằng NWPathMonitor
sẽ chạy pathUpdateHandler
nếu bất kì thuộc tính nào của connection thay đổi. Tuỳ nghiệp vụ mà bạn có thể quan tâm đến tất cả các thuộc tính hoặc không, tuy nhiên giả sử như chỉ muốn biết về loại kết nối và tình trạng kết nối thì bạn sẽ gặp trường hợp pathUpdateHandler
bị gọi nhiều lần khi những thông tin không cần thiết thay đổi.
ConnectionObserver
Để đơn giản hoá việc sử dụng và giới hạn những thông tin quan trọng của connection ta sẽ bọc NWPathMonitor
trong class ConnectionObserver
.
import Network
protocol ConnectionAttribute: Equatable {
init(path: NWPath)
}
class ConnectionObserver<T: ConnectionAttribute> {
var handler: ((T) -> Void)?
private var monitor: NWPathMonitor
private(set) var attribute: T {
didSet {
guard oldValue != attribute else { return }
handler?(attribute)
}
}
deinit {
cancel()
}
init(monitor: NWPathMonitor = NWPathMonitor(),
queue: DispatchQueue = .main,
handler: ((T) -> Void)? = nil) {
self.monitor = monitor
self.attribute = T(path: monitor.currentPath)
self.handler = handler
self.monitor.start(queue: queue)
self.monitor.pathUpdateHandler = { [weak self] path in
self?.attribute = T(path: path)
}
}
func cancel() {
monitor.cancel()
}
}
Protocol ConnectionAttribute
đại diện cho những thuộc tính chúng ta quan tâm. Các struct/class conform protocol này sẽ lấy thông tin phù hợp từ NWPath
.
Mỗi khi pathUpdateHandler
chạy, ConnectionObserver
sử dụng NWPath
truyền vào để khởi tạo và lưu attribute
mới. Bởi ConnectionAttribute
tuân thủ Equatable
, ta sẽ chỉ chạy closure handler
khi attribute
mới khác attribute
cũ, giúp giải quyết vấn đề nêu ở phần trước.
Việc sử dụng ConnectionObserver
rất đơn giản và dễ hiểu
struct BasicConnectionAttribute: Equatable, ConnectionAttribute {
let isExpensive: Bool
let hasConnection: Bool
init(path: NWPath) {
isExpensive = path.isExpensive
hasConnection = path.status == .satisfied
}
}
let observer = ConnectionObserver<BasicConnectionAttribute>() { [weak self] attribute in
//Logic khi connection thay đổi ...
}
Tổng kết
Với NWPathMonitor
chúng ta đã có thể loại bỏ những thư viện bên thứ ba cồng kềnh. Tuy nhiên, mình xin chia buồn tới những bạn vẫn phải support iOS 11 nhé 😢.
Source code: ConnectionObserver