1

I'm using Reachability of ashleymills: https://github.com/ashleymills/Reachability.swift/releases

In Xcode 7, I wrote a function to display an alert of reachability status.

However, the alert never shows up.

Here is my code:

let reachability = Reachability.reachabilityForInternetConnection()
reachability!.whenReachable = { reachability in
    if reachability.isReachableViaWiFi() {
        let alertController = UIAlertController(title: "Alert", message: "Reachable via WiFi", preferredStyle: .Alert)
        let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)

        alertController.addAction(defaultAction)

        self.presentViewController(alertController, animated: true, completion: nil)
    }
    else {
        let alertController = UIAlertController(title: "Alert", message: "Reachable via Cellular", preferredStyle: .Alert)
        let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)

        alertController.addAction(defaultAction)

        self.presentViewController(alertController, animated: true, completion: nil)
    }
}

reachability!.whenUnreachable = { reachability in
    let alertController = UIAlertController(title: "Alert", message: "Please connect to internet", preferredStyle: .Alert)
    let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)

    alertController.addAction(defaultAction)

    self.presentViewController(alertController, animated: true, completion: nil)
}

reachability!.startNotifier()
Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
GPH
  • 1,111
  • 6
  • 29
  • 49
  • I think the problem may be that the closure isn't called on the main thread, so wrapping your `UIAlertController` code in `dispatch_async(dispatch_get_main_queue()) { … }` should resolve it – Ashley Mills Oct 05 '15 at 09:55

1 Answers1

0

Please replace your code with this and it should work, there might be a bug in Reachability after swift 1.2, so here I'm just checking if its reachable or not and i think its enough.

In my opinion you don't have to check if its the wifi or cellular, The reason behind the alert isn't showing because its not entering the blocks to show the alert :

let useClosures = false

class ViewController: UIViewController {

    let reachability = Reachability.reachabilityForInternetConnection()

    override func viewDidLoad() {
        super.viewDidLoad()

        if (useClosures) {
            reachability?.whenReachable = { reachability in
                print("Reachable")
            }
            reachability?.whenUnreachable = { reachability in
                print("Unreachable")
            }
        } else {
            NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name: ReachabilityChangedNotification, object: reachability)
        }

        reachability?.startNotifier()

        // Initial reachability check when the app starts
        if let reachability = reachability {
              dispatch_async(dispatch_get_main_queue()) {
            if reachability.isReachable() {
                let alertController = UIAlertController(title: "Alert", message: "Reachable", preferredStyle: .Alert)
                let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)

                alertController.addAction(defaultAction)

                self.presentViewController(alertController, animated: true, completion: nil)
            } else {
                let alertController = UIAlertController(title: "Alert", message: "Please connect to internet", preferredStyle: .Alert)
                let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)

                alertController.addAction(defaultAction)

                self.presentViewController(alertController, animated: true, completion: nil)
            }
            }
        }
    }

    deinit {

        reachability?.stopNotifier()

        if (!useClosures) {
            NSNotificationCenter.defaultCenter().removeObserver(self, name: ReachabilityChangedNotification, object: nil)
        }
    }


    func reachabilityChanged(note: NSNotification) {
        let reachability = note.object as! Reachability
        // Initial reachability check while surfing in the app
        if reachability.isReachable() {
            let alertController = UIAlertController(title: "Alert", message: "Reachable", preferredStyle: .Alert)
            let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)

            alertController.addAction(defaultAction)

            self.presentViewController(alertController, animated: true, completion: nil)

        } else {
            let alertController = UIAlertController(title: "Alert", message: "Please connect to internet", preferredStyle: .Alert)
            let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)

            alertController.addAction(defaultAction)

            self.presentViewController(alertController, animated: true, completion: nil)
        }
    }
}

Note : You said you have webView in your app, remember that you have to refresh or update when its reachable.

AaoIi
  • 8,288
  • 6
  • 45
  • 87
  • Thank you! Just test your code, but the alert never shows up. – GPH Oct 04 '15 at 17:54
  • @GPH , where are you placing this code ? in `viewDidLoad` ? btw in my case its showing ! – AaoIi Oct 04 '15 at 17:57
  • Yes, in the viewDidLoad function of ViewController.swift – GPH Oct 04 '15 at 18:02
  • it only shows up when starting the app, if the internet connection change after starting the app, it didn't show the alert. Btw the webview can't display anything after adding the code. – GPH Oct 04 '15 at 18:20
  • I fix some of my problem and add your code. it show error as below – GPH Oct 05 '15 at 08:47
  • /Volumes/web/MAC/untitled folder/hksalonhk/hksalonhk/SecondViewController.swift:23:13: Initialization of immutable value 'useClosures' was never used; consider replacing with assignment to '_' or removing it /Volumes/web/MAC/untitled folder/hksalonhk/hksalonhk/SecondViewController.swift:32:21: Class declaration cannot close over value 'useClosures' defined in outer scope /Volumes/web/MAC/untitled folder/hksalonhk/hksalonhk/SecondViewController.swift:71:22: Class declaration cannot close over value 'useClosures' defined in outer scope – GPH Oct 05 '15 at 08:47
  • Everything is fine now, thank you very much! I made some mistake before. – GPH Oct 05 '15 at 09:02