4

In my viewDidLoad() function I call this method:

//MARK: Reachability
func startReachability(){
    //declare this property where it won't go out of scope relative to your listener
    do{
        let reachability = try Reachability.reachabilityForInternetConnection()

        reachability.whenReachable = { reachability in
            // this is called on a background thread, but UI updates must
            // be on the main thread, like this:
            dispatch_async(dispatch_get_main_queue()) {
                if reachability.isReachableViaWiFi() {
                    print("Reachable via WiFi")
                } else {
                    print("Reachable via Cellular")
                }
            }
        }
        reachability.whenUnreachable = { reachability in
            // this is called on a background thread, but UI updates must
            // be on the main thread, like this:
            dispatch_async(dispatch_get_main_queue()) {
                print("Not reachable")
            }
        }

        try reachability.startNotifier()

    } catch {
        print("Unable to start notifier")
    }
}

But it does not work. It calls whenReachable() and whenUnreachable() only once and when I turn Wi-Fi off and on it does nothing.

Oleg Gordiichuk
  • 15,240
  • 7
  • 60
  • 100
Marina
  • 1,177
  • 4
  • 14
  • 27

3 Answers3

3

I needed a strong reference to Reachability instance! So I should have declared it at a class level.

Marina
  • 1,177
  • 4
  • 14
  • 27
1

It will validate your network only when you directly call this method.If you would like to receive notification on the network richability change you should use richability notifications.

Observer notifications.

//declare this property where it won't go out of scope relative to your listener
let reachability = Reachability()!

//declare this inside of viewWillAppear

NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:",name: ReachabilityChangedNotification,object: reachability)
do{
  try reachability.startNotifier()
}catch{
  print("could not start reachability notifier")
}

Handle changes:

func reachabilityChanged(note: NSNotification) {

  let reachability = note.object as! Reachability

  if reachability.isReachable() {
    if reachability.isReachableViaWiFi() {
      print("Reachable via WiFi")
    } else {
      print("Reachable via Cellular")
    }
  } else {
    print("Network not reachable")
  }
}

Unsubscribe:

reachability.stopNotifier()
NSNotificationCenter.defaultCenter().removeObserver(self,
                                                    name: ReachabilityChangedNotification,
                                                    object: reachability)
Mo Abdul-Hameed
  • 6,030
  • 2
  • 23
  • 36
Oleg Gordiichuk
  • 15,240
  • 7
  • 60
  • 100
1

In Swift 4 i have issue whenReachable clouser not execute. I found that All notifications should delivere on the main queue.

Solve using below code

//declare this property at top of your file, so the scope will remain.

let reachability = Reachability()!

 func setUpReachability()
    {
        //declare this property where it won't go out of scope relative to your listener
        DispatchQueue.main.async {

            self.reachability.whenReachable = { reachability in
            if reachability.connection == .wifi {
                print("Reachable via WiFi")
            } else {
                print("Reachable via Cellular")
            }
        }
            self.self.reachability.whenUnreachable = { _ in
            print("Not reachable")
        }

        do {
            try self.reachability.startNotifier()
        } catch {
            print("Unable to start notifier")
        }

        }
    }
guru
  • 2,727
  • 3
  • 27
  • 39