swiftreachabilityreachability-swift

How to test for iPhone connection to internet with swift 4?


For Swift 4/xcode:
I have scoured the internet for a solution to this issue, but I have yet to find a definitive, comprehensive answer that covers all of the bases. There are several on Stack that answer the question to some extent, including swift specific answers such as these or AshleyMills Reachability, but many are old and not comprehensive.
1. I want the method to check for internet connection, not just connection to wifi. Several of the methods online merely check for connection to Wi-Fi, but do not confirm that internet is available via the wifi. I want a method that only returns true if internet connection is detected.
2. This method must also return true for cellular data usage. Yes Wi-Fi can provide internet connection, but so can data. This method needs to be comprehensive enough to return true if either or both cellular/wifi internet is provided.
Lastly, a note. The fact that there isn't a full swift answer online that checks all of the boxes makes me wonder if my approach to this issue is incorrect in a more general sense. My app needs to load data from a database, which is why it needs the internet connection. This is an extremely common thing for popular apps nowadays. Apps don't crash from trying to load their data without internet connection. What I am thinking they do (which is the basis for this question) is as so:

if doesHaveInternetConnection{
    //run loading data functions
}else{
    //don't run loading data functions
}

Is this not the way it is done? If not, what is the better way to approach this problem?


Solution

  • Here is a list of URLErrors when making a network request. In the list, there is an enum value called notConnectedToInternet. When you make a network request and it fails, look at the error code to find out if it is due to no connectivity or something else.

    Alternatively, you can host a health-check end-point on your server. Before making any request, make a request to this end-point. If the request is successful, you can rest assured that there is internet connectivity. Although, I would highly recommend going with the first option.

    Example

    NOTE: The code below is in Swift 3.

    URLSession.shared.dataTask(with: *URLRequest*) { (data, response, error) -> Void in
        if error != nil {
            if let e = error as? URLError, e.code == .notConnectedToInternet {
                //Not connected to internet
            } else {
                //Some other error
            }
        } else {
            //The request was successful
        }
    }.resume()