network bad ios swift nsnotificationcenter reachability

bad - Detección de cambios en la conectividad de la red mediante la accesibilidad, NSNotification y Network Link Conditioner en Swift



reachability ios (8)

Estoy tratando de integrar la detección de conectividad de red en mi aplicación, sin embargo, parece que en algún momento he cometido un error, ya que mis cambios de red no se detectan / imprimen en la consola.

Como se menciona en la publicación, actualmente estoy usando estas siguientes clases y herramientas para el trabajo:

  1. Accesibilidad {.h, .m}
  2. NSNotificationCenter
  3. Acondicionador de enlace de red

Código

En AppDelegate.Swift , configuré NSNotificationCenter para detectar cambios:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // ... // A: Checks if the device is connected to the internet var defaultCenter: Void = NSNotificationCenter().addObserver(self, selector:"checkForReachability", name: kReachabilityChangedNotification, object: nil)

}

En la misma clase AppDelegate , también he creado esta función para que se active siempre que haya un cambio:

func checkForReachability () { var networkReachability = Reachability.reachabilityForInternetConnection() networkReachability.startNotifier() var remoteHostStatus = networkReachability.currentReachabilityStatus() if (remoteHostStatus.value == NotReachable.value) { println("Not Reachable") } else if (remoteHostStatus.value == ReachableViaWiFi.value) { println("Reachable via Wifi") } else { println("Reachable") } }

Sin embargo, cuando uso el Acondicionador de enlace de red para manipular y simular cambios en las condiciones, no he podido ver ninguno de esos cambios reflejados en la consola. Cualquier ayuda sería genial!


1) Instale pod o agregue ReachabilitySwift en su proyecto

2) en AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(self.checkForReachability(_:)), name: "ReachabilityChangedNotification", object: nil); do { try self.reachability = Reachability.reachabilityForInternetConnection() } catch { print(error) } do { try self.reachability.startNotifier() } catch { print(error) } return true }

3)

func checkForReachability(notification:NSNotification) { let networkReachability = notification.object as! Reachability; let remoteHostStatus = networkReachability.currentReachabilityStatus if (remoteHostStatus == .NotReachable) { print("Not Reachable") } else if (remoteHostStatus == .ReachableViaWiFi || remoteHostStatus == .ReachableViaWWAN) { print("Reachable via Wifi or via WWAN") } }


Basado en esta solución de código abierto Envuelto en clase

Swift 5

import Foundation final class ReachabilityHandler { private var reachability: Reachability? = Reachability() // MARK: - LifeCycle init() { configure() } deinit { NotificationCenter.default.removeObserver(self) reachability?.stopNotifier() } // MARK: - Private private func configure() { NotificationCenter.default.addObserver(self, selector: #selector(ReachabilityHandler.checkForReachability(notification:)), name: Notification.Name.reachabilityChanged, object: nil) try? reachability?.startNotifier() } @objc private func checkForReachability(notification: NSNotification) { let networkReachability = notification.object as? Reachability if let remoteHostStatus = networkReachability?.connection { switch remoteHostStatus { case .none: case .wifi, .cellular: } } } }

En AppDelegate

class AppDelegate: UIResponder, UIApplicationDelegate { private var rechabilityObserver: ReachabilityHandler? var window: UIWindow? // MARK: - LifeCycle func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { rechabilityObserver = ReachabilityHandler() return true } }


Debe crear un objeto de Accesibilidad antes de poder recibir notificaciones de él. Además, asegúrese de llamar al método startNotifier() en el objeto de accesibilidad que cree. Este sería un ejemplo de cómo hacerlo dentro del delegado de su aplicación:

class AppDelegate: UIResponder, UIApplicationDelegate { private var reachability:Reachability!; func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { NSNotificationCenter.defaultCenter().addObserver(self, selector:"checkForReachability:", name: kReachabilityChangedNotification, object: nil); self.reachability = Reachability.reachabilityForInternetConnection(); self.reachability.startNotifier(); } @objc func checkForReachability(notification:NSNotification) { // Remove the next two lines of code. You cannot instantiate the object // you want to receive notifications from inside of the notification // handler that is meant for the notifications it emits. //var networkReachability = Reachability.reachabilityForInternetConnection() //networkReachability.startNotifier() let networkReachability = notification.object as Reachability; var remoteHostStatus = networkReachability.currentReachabilityStatus() if (remoteHostStatus.value == NotReachable.value) { println("Not Reachable") } else if (remoteHostStatus.value == ReachableViaWiFi.value) { println("Reachable via Wifi") } else { println("Reachable") } } }

Le recomiendo que eche un vistazo a la documentación de NSNotificationCenter y NSNotification . De esa manera, estará más familiarizado con la forma de trabajar con las notificaciones la próxima vez que surja algo como esto.

Swift 3

NotificationCenter.default.addObserver(self, selector:Selector(("checkForReachability:")), name: NSNotification.Name.reachabilityChanged, object: nil) let reachability: Reachability = Reachability.forInternetConnection() reachability.startNotifier()


En lugar de contaminar el AppDelegate.swift con devoluciones de llamada de observador, recomendaría agregar observadores solo en los controladores de vista relevantes.

AppDelegate.swift

import ReachabilitySwift @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var reachability: Reachability? func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? ) -> Bool { self.reachability = Reachability() do { try reachability?.startNotifier() } catch { print( "ERROR: Could not start reachability notifier." ) } return true } class func sharedAppDelegate() -> AppDelegate? { return UIApplication.shared.delegate as? AppDelegate } // Remaining functions }

Ejemplo de un ViewController:

class ExampleVC: UIViewController { override func viewDidLoad() { // Add reachability observer if let reachability = AppDelegate.sharedAppDelegate()?.reachability { NotificationCenter.default.addObserver( self, selector: #selector( self.reachabilityChanged ),name: ReachabilityChangedNotification, object: reachability ) } } @objc private func reachabilityChanged( notification: NSNotification ) { guard let reachability = notification.object as? Reachability else { return } if reachability.isReachable { if reachability.isReachableViaWiFi { print("Reachable via WiFi") } else { print("Reachable via Cellular") } } else { print("Network not reachable") } } }


Respuesta actualizada de AR Younce para Swift 2:

func checkForReachability(notification:NSNotification) { if let networkReachability = notification.object as? Reachability { let remoteHostStatus = networkReachability.currentReachabilityStatus() if (remoteHostStatus == NotReachable) { print("Not Reachable") } else if (remoteHostStatus == ReachableViaWiFi) { print("Reachable via Wifi") } else { print("Reachable") } } else { print("Unknown") } }


Actualizado para Swift 4 / Swift 5 según @ Hardik.T

1. Importe el archivo Reachability.swift desde https://github.com/ashleymills/Reachability.swift/archive/master.zip en su proyecto XCode

2. Cree una nueva clase Swift: ConnectionManager.swift

class ConnectionManager { static let sharedInstance = ConnectionManager() private var reachability : Reachability! func observeReachability(){ self.reachability = Reachability() NotificationCenter.default.addObserver(self, selector:#selector(self.reachabilityChanged), name: NSNotification.Name.reachabilityChanged, object: nil) do { try self.reachability.startNotifier() } catch(let error) { print("Error occured while starting reachability notifications : /(error.localizedDescription)") } } @objc func reachabilityChanged(note: Notification) { let reachability = note.object as! Reachability switch reachability.connection { case .cellular: print("Network available via Cellular Data.") break case .wifi: print("Network available via WiFi.") break case .none: print("Network is not available.") break } } }

3. Úselo en su archivo AppDelegate :

func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { ConnectionManager.sharedInstance.observeReachability() return true }


Actualizado para swift 2.1 y XCode 7:

prueba esta clase de accesibilidad altamente calificada de terceros

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { // Allocate a reachability object self.reach = Reachability.reachabilityForInternetConnection() // Tell the reachability that we DON''T want to be reachable on 3G/EDGE/CDMA self.reach!.reachableOnWWAN = false // Here we set up a NSNotification observer. The Reachability that caused the notification // is passed in the object parameter NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name: kReachabilityChangedNotification, object: nil) self.reach!.startNotifier() return true } //Reachbality Notification Response func reachabilityChanged(notification: NSNotification) { if self.reach!.isReachableViaWiFi() || self.reach!.isReachableViaWWAN() { print("Service avalaible!!!") } else { print("No service avalaible!!!") AppHelper.showALertWithTag(0, title: constants.AppName.rawValue, message: "Please Check Your Internet Connection!", delegate: self, cancelButtonTitle: "OK", otherButtonTitle: nil) } }


Swift 2.0 - Verifique la red utilizando la accesibilidad, NSNotification

AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(self.checkNetworkStatus(_:)), name: "ReachabilityChangedNotification", object: nil); do{self.reachability = try Reachability.reachabilityForInternetConnection()}catch{} do{try self.reachability.startNotifier()}catch{} self.checkNetworkStatus() return true }

Declarar variable networkStatus

var networkStatus : Reachability.NetworkStatus!

Función checkNetworkStatus ()

func checkNetworkStatus() { networkStatus = reachability.currentReachabilityStatus if (networkStatus == Reachability.NetworkStatus.NotReachable) { print("Not Reachable") } else { print("Reachable") } }

OtherClass.Swift

let delegate = UIApplication.sharedApplication().delegate as! AppDelegate if (delegate.networkStatus!=Reachability.NetworkStatus.NotReachable) { // Call Webservice } else { delegate.checkNetworkStatus() //Not Reachable print }