Advertisement
Guest User

Untitled

a guest
Jul 16th, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 4.51 KB | None | 0 0
  1. import Foundation
  2. import SystemConfiguration
  3.  
  4. protocol NetworkReachabilityHandlerDelegate {
  5.     func networkReachabilityHandler(_ handler: NetworkReachabilityHandler, reachabilityChangedTo isReachable: Bool)
  6. }
  7.  
  8. final class NetworkReachabilityHandler {
  9.     static let checkForReachabilityNotification = Notification.Name(rawValue: "CheckForReachability")
  10.     static let connectionEstablishedNotification = Notification.Name(rawValue: "ConnectionEstablished")
  11.     static let connectionLostNotification = Notification.Name(rawValue: "ConnectionLost")
  12.    
  13.     private let reachability = SCNetworkReachabilityCreateWithName(nil, URLBuilder.CustomURL.hrmWebsite.rawValue) //change to "https://www.google.com/"
  14.     private let queue = DispatchQueue.main
  15.     private var currentReachabilityFlags: SCNetworkReachabilityFlags?
  16.     private var isListening = false
  17.    
  18.     var delegate: NetworkReachabilityHandlerDelegate?
  19.    
  20.     // MARK: - Public methods
  21.    
  22.     func startListening() {
  23.         guard !isListening else { return }
  24.         guard let reachability = reachability else { return }
  25.        
  26.         NotificationCenter.default.addObserver(self, selector: #selector(checkCurrentReachabilityAndNotify), name: NetworkReachabilityHandler.checkForReachabilityNotification, object: nil)
  27.         var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
  28.         context.info = UnsafeMutableRawPointer(Unmanaged<NetworkReachabilityHandler>.passUnretained(self).toOpaque())
  29.        
  30.         let callbackClosure: SCNetworkReachabilityCallBack? = { (reachability: SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) in
  31.             guard let info = info else { return }
  32.             let handler = Unmanaged<NetworkReachabilityHandler>.fromOpaque(info).takeUnretainedValue()
  33.            
  34.             DispatchQueue.main.async {
  35.                 handler.checkReachability(flags: flags)
  36.             }
  37.         }
  38.        
  39.         SCNetworkReachabilitySetCallback(reachability, callbackClosure, &context)
  40.         SCNetworkReachabilitySetDispatchQueue(reachability, self.queue)
  41.        
  42.         queue.async {
  43.             self.currentReachabilityFlags = nil
  44.             var flags = SCNetworkReachabilityFlags()
  45.             SCNetworkReachabilityGetFlags(reachability, &flags)
  46.             self.checkReachability(flags: flags)
  47.         }
  48.        
  49.         isListening = true
  50.     }
  51.    
  52.     func stopListening() {
  53.         guard isListening, let reachability = reachability else { return }
  54.         NotificationCenter.default.removeObserver(self, name: NetworkReachabilityHandler.checkForReachabilityNotification, object: nil)
  55.         SCNetworkReachabilitySetCallback(reachability, nil, nil)
  56.         SCNetworkReachabilitySetDispatchQueue(reachability, nil)
  57.         isListening = false
  58.     }
  59.    
  60.     //MARK: - Private Methods
  61.    
  62.     private func checkReachability(flags: SCNetworkReachabilityFlags) {
  63.         guard currentReachabilityFlags != flags else { return }
  64.         notifyChangePerceived(from: flags)
  65.         currentReachabilityFlags = flags
  66.     }
  67.    
  68.     private func notifyChangePerceived(from flags: SCNetworkReachabilityFlags) {
  69.         if delegate != nil {
  70.             delegate?.networkReachabilityHandler(self, reachabilityChangedTo: isNetworkReachable(with: flags))
  71.         } else {
  72.             postAccordingNotification(from: flags)
  73.         }
  74.     }
  75.    
  76.     private func isNetworkReachable(with flags: SCNetworkReachabilityFlags) -> Bool {
  77.         let isReachable = flags.contains(.reachable)
  78.         let needsConnection = flags.contains(.connectionRequired)
  79.         let canConnectAutomatically = flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic)
  80.         let canConnectWithoutUserInteraction = canConnectAutomatically && !flags.contains(.interventionRequired)
  81.        
  82.         return isReachable && (!needsConnection || canConnectWithoutUserInteraction)
  83.     }
  84.    
  85.     private func postAccordingNotification(from flags: SCNetworkReachabilityFlags) {
  86.         let accordingNotificationName = isNetworkReachable(with: flags) ? NetworkReachabilityHandler.connectionEstablishedNotification : NetworkReachabilityHandler.connectionLostNotification
  87.         NotificationCenter.default.post(name: accordingNotificationName, object: nil)
  88.     }
  89.    
  90.     @objc private func checkCurrentReachabilityAndNotify() {
  91.         guard let flags = currentReachabilityFlags else { return }
  92.         notifyChangePerceived(from: flags)
  93.     }
  94. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement