Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Foundation
- import SystemConfiguration
- protocol NetworkReachabilityHandlerDelegate {
- func networkReachabilityHandler(_ handler: NetworkReachabilityHandler, reachabilityChangedTo isReachable: Bool)
- }
- final class NetworkReachabilityHandler {
- static let checkForReachabilityNotification = Notification.Name(rawValue: "CheckForReachability")
- static let connectionEstablishedNotification = Notification.Name(rawValue: "ConnectionEstablished")
- static let connectionLostNotification = Notification.Name(rawValue: "ConnectionLost")
- private let reachability = SCNetworkReachabilityCreateWithName(nil, URLBuilder.CustomURL.hrmWebsite.rawValue) //change to "https://www.google.com/"
- private let queue = DispatchQueue.main
- private var currentReachabilityFlags: SCNetworkReachabilityFlags?
- private var isListening = false
- var delegate: NetworkReachabilityHandlerDelegate?
- // MARK: - Public methods
- func startListening() {
- guard !isListening else { return }
- guard let reachability = reachability else { return }
- NotificationCenter.default.addObserver(self, selector: #selector(checkCurrentReachabilityAndNotify), name: NetworkReachabilityHandler.checkForReachabilityNotification, object: nil)
- var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
- context.info = UnsafeMutableRawPointer(Unmanaged<NetworkReachabilityHandler>.passUnretained(self).toOpaque())
- let callbackClosure: SCNetworkReachabilityCallBack? = { (reachability: SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) in
- guard let info = info else { return }
- let handler = Unmanaged<NetworkReachabilityHandler>.fromOpaque(info).takeUnretainedValue()
- DispatchQueue.main.async {
- handler.checkReachability(flags: flags)
- }
- }
- SCNetworkReachabilitySetCallback(reachability, callbackClosure, &context)
- SCNetworkReachabilitySetDispatchQueue(reachability, self.queue)
- queue.async {
- self.currentReachabilityFlags = nil
- var flags = SCNetworkReachabilityFlags()
- SCNetworkReachabilityGetFlags(reachability, &flags)
- self.checkReachability(flags: flags)
- }
- isListening = true
- }
- func stopListening() {
- guard isListening, let reachability = reachability else { return }
- NotificationCenter.default.removeObserver(self, name: NetworkReachabilityHandler.checkForReachabilityNotification, object: nil)
- SCNetworkReachabilitySetCallback(reachability, nil, nil)
- SCNetworkReachabilitySetDispatchQueue(reachability, nil)
- isListening = false
- }
- //MARK: - Private Methods
- private func checkReachability(flags: SCNetworkReachabilityFlags) {
- guard currentReachabilityFlags != flags else { return }
- notifyChangePerceived(from: flags)
- currentReachabilityFlags = flags
- }
- private func notifyChangePerceived(from flags: SCNetworkReachabilityFlags) {
- if delegate != nil {
- delegate?.networkReachabilityHandler(self, reachabilityChangedTo: isNetworkReachable(with: flags))
- } else {
- postAccordingNotification(from: flags)
- }
- }
- private func isNetworkReachable(with flags: SCNetworkReachabilityFlags) -> Bool {
- let isReachable = flags.contains(.reachable)
- let needsConnection = flags.contains(.connectionRequired)
- let canConnectAutomatically = flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic)
- let canConnectWithoutUserInteraction = canConnectAutomatically && !flags.contains(.interventionRequired)
- return isReachable && (!needsConnection || canConnectWithoutUserInteraction)
- }
- private func postAccordingNotification(from flags: SCNetworkReachabilityFlags) {
- let accordingNotificationName = isNetworkReachable(with: flags) ? NetworkReachabilityHandler.connectionEstablishedNotification : NetworkReachabilityHandler.connectionLostNotification
- NotificationCenter.default.post(name: accordingNotificationName, object: nil)
- }
- @objc private func checkCurrentReachabilityAndNotify() {
- guard let flags = currentReachabilityFlags else { return }
- notifyChangePerceived(from: flags)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement