Search code examples
iosswift3uialertviewxcode8reachability

Detect Internet Connection and display UIAlertview Swift 3


I am making an app that detects if there is a connection to internet by using if else statement, when there is internet, do nothing but if there are no internet connection, then alert view to say the app requires an internet I managed found Reachability but to implement on my viewDidLoad() the uialertview seems to be not working. I am using this:

public class Reachability {
class func isConnectedToNetwork() -> Bool {
    var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)

    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
        }
    }
    var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
    if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
        return false
    }
    let isReachable = flags == .reachable
    let needsConnection = flags == .connectionRequired
    return isReachable && !needsConnection
    }
}

then in my View Controller class:

override func viewDidLoad() {
        if Reachability.isConnectedToNetwork() == true
        {
            print("Connected")
        }
        else
        {
            let controller = UIAlertController(title: "No Internet Detected", message: "This app requires an Internet connection", preferredStyle: .alert)
            let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
            let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)

            controller.addAction(ok)
            controller.addAction(cancel)

            present(controller, animated: true, completion: nil)
        }
        super.viewDidLoad()
        //...
    }

and looks like the alertview doesn't popup any suggestion? or help? thanks


Solution

  • You have to put the AlertController in the viewDidAppear method of your ViewControllers lifecycle, because in the methods viewDidLoad und viewWillAppear your current view is still not in the window hierachy.
    If you want to present further ViewControllers like the AlertController you need a full loaded view in which your new ViewController could be rendered:

    override func viewDidLoad() {
        super.viewDidLoad()
        //ViewControllers view not in the window hierarchy
        // Here you could make further initialization of your views subviews
    }
    
    override func viewWillAppear(_ animated: Bool) {
        //ViewControllers view ist still not in the window hierarchy
        //This is the right place to do for instance animations on your views subviews
    }
    
    override func viewDidAppear(_ animated: Bool) {
        // ViewControllers view ist fully loaded and could present further ViewController
        //Here you could do any other UI operations
        if Reachability.isConnectedToNetwork() == true
        {
            print("Connected")
        }
        else
        {
            let controller = UIAlertController(title: "No Internet Detected", message: "This app requires an Internet connection", preferredStyle: .alert)
            let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
            let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
    
            controller.addAction(ok)
            controller.addAction(cancel)
    
            present(controller, animated: true, completion: nil)
        }
    
    }
    

    This is what the Apple documentation is saying about ViewController: UIViewController methods get called as follows:

    • viewDidLoad()—Called when the view controller’s content view (the top of its view hierarchy) is created and loaded from a storyboard. This method is intended for initial setup. However, because views may be purged due to limited resources in an app, there is no guarantee that it will be called only once.
    • viewWillAppear()—Intended for any operations that you want always to occur before the view becomes visible. Because a view’s visibility may be toggled or obscured by other views, this method is always called immediately before the content view appears onscreen.
    • viewDidAppear()—Intended for any operations that you want to occur as soon as the view becomes visible, such as fetching data or showing an animation. Because a view’s visibility may be toggled or obscured by other views, this method is always called immediately after the content view appears onscreen.

    Reference: https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson4.html