How to check internet connection in alamofire?

40,844

Solution 1

For swift 5 and Alamofire 5.4.4 ,I created a swift class called Connectivity . Use NetworkReachabilityManager class from Alamofire and configure the isConnectedToInternet() method as per your need.

import Foundation
import Alamofire

class Connectivity {
    class func isConnectedToInternet() -> Bool {
        return NetworkReachabilityManager()?.isReachable ?? false
    }
}

Usage:

if Connectivity.isConnectedToInternet() {
        print("Yes! internet is available.")
        // do some tasks..
 }

EDIT: Since swift is encouraging computed properties, you can change the above function like:

import Foundation
import Alamofire
class Connectivity {
    class var isConnectedToInternet:Bool {
        return NetworkReachabilityManager()?.isReachable ?? false
    }
}

and use it like:

if Connectivity.isConnectedToInternet {
        print("Yes! internet is available.")
        // do some tasks..
 }

Solution 2

Swift 2.3

Alamofire.request(.POST, url).responseJSON { response in
switch response.result {
    case .Success(let json):
        // internet works.  
    case .Failure(let error):

        if let err = error as? NSURLError where err == .NotConnectedToInternet {
            // no internet connection
        } else {
            // other failures
        }
    }
}

Swift 3.0

  Alamofire.upload(multipartFormData: { multipartFormData in
    }, to: URL, method: .post,headers: nil,
       encodingCompletion:  { (result) in
        switch result {

        case .success( _, _, _): break

        case .failure(let encodingError ):
            print(encodingError)

            if let err = encodingError as? URLError, err.code == .notConnectedToInternet {
                // no internet connection
                print(err)
            } else {
                // other failures
            }

        }
    })

Using NetworkReachabilityManager

let networkReachabilityManager = Alamofire.NetworkReachabilityManager(host: "www.apple.com")

func checkForReachability() {
    self.networkReachabilityManager?.listener = { status in
        print("Network Status: \(status)")
        switch status {
        case .notReachable:
            //Show error here (no internet connection)
        case .reachable(_), .unknown:
            //Hide error here
        }
    }

    self.networkReachabilityManager?.startListening()
}

//How to Use : Just call below function in required class
if checkForReachability() {
   print("connected with network")
}

Solution 3

For Swift 3/4,

In Alamofire, there is a class called NetworkReachabilityManager which can be used to observer or check if internet is available or not.

let reachabilityManager = NetworkReachabilityManager()

reachabilityManager?.startListening()
reachabilityManager?.listener = { _ in
        if let isNetworkReachable = self.reachabilityManager?.isReachable,
            isNetworkReachable == true {
            //Internet Available
        } else {
            //Internet Not Available"
        }
    }

Here, listener will get called every time when there is changes in state of internet. You can handle it as you would like.

Solution 4

If Alamofire.upload result returns success then below is the way to check for internet availibility while uploading an image:

Alamofire.upload(multipartFormData: { multipartFormData in

                for (key,value) in parameters {
                 multipartFormData.append((value).data(using: .utf8)!, withName: key)
                }
                  multipartFormData.append(self.imageData!, withName: "image" ,fileName: "image.jpg" , mimeType: "image/jpeg")
            }, to:url)
            { (result) in

                switch result{

                case .success(let upload, _, _):

                    upload.uploadProgress(closure: { (progress) in
                     print("Upload Progress: \(progress.fractionCompleted)")

                    })

                    upload.responseJSON { response in
                        if  let statusCode = response.response?.statusCode{

                        if(statusCode == 201){
                         //internet available
                          }
                        }else{
                        //internet not available

                        }
                    }

                case .failure(let encodingError):
                    print(encodingError)

                }

            }

Solution 5

In general if you can get the internet offline information from the actual call, its better than reachability. You can be certain that the actual API call has failed because the internet is down. If you test for reachability before you call an API and it fails then all you know is that when the test was done the internet was offline ( or Apple was down), you don't know that when you make the call the internet will be offline. You might think it is a matter of milliseconds after the reachability call returns, or you retrieved the stored value, but thats in fact non deterministic. The OS might have scheduled some arbitrary number of threads before reachability returns its values in its closure, or updates whatever global you are storing.

And reachability has historically had bugs in its own code.

This isn't to say that you shouldn't use alamofire's NetworkReachabilityManager to change your UI, listen to it and update all the UI components.

But if you have reason to call an API, at that API layer the test for reachability is redundant, or possibly will cause some subtle bugs.

Share:
40,844
TechChain
Author by

TechChain

I have 4+ of experience of overall experience.Currently working on Hyperledger Fabric blockchain framework. I have strong knowledge of Objective c, Swift.I have developed lot of apps from chat app, finance apps,location & map based apps.

Updated on January 13, 2022

Comments

  • TechChain
    TechChain over 2 years

    I am using below code for making HTTP request in server.Now I want to know whether it is connected to internet or not. Below is my code

      let request = Alamofire.request(completeURL(domainName: path), method: method, parameters: parameters, encoding: encoding.value, headers: headers)
          .responseJSON {
    
    
            let resstr = NSString(data: $0.data!, encoding: String.Encoding.utf8.rawValue)
            print("error is \(resstr)")
    
    
            if $0.result.isFailure {
              self.failure("Network")
              print("API FAILED 4")
              return
            }
            guard let result = $0.result.value else {
              self.unKnownError()
              self.failure("")
              print("API FAILED 3")
    
              return
            }
            self.handleSuccess(JSON(result))
        }
    
  • TechChain
    TechChain over 7 years
    I want to do it by alamofire not reachibilty
  • TechChain
    TechChain over 7 years
    please give soluton in alamofire only
  • Umair Afzal
    Umair Afzal over 7 years
    It is a part of alamofire
  • MAhipal Singh
    MAhipal Singh over 7 years
    let reachabilityManager = Alamofire.NetworkReachabilityManager(host: "www.apple.com") func listenForReachability() { reachabilityManager?.listener = { status in print("Network Status Changed: (status)") switch status { case .NotReachable: break //Show error state case .Reachable(_), .Unknown: break //Hide error state } } reachabilityManager?.startListening() }
  • TechChain
    TechChain over 7 years
    i cant follow this approach please review my code & provide solution
  • Andreas777
    Andreas777 about 7 years
    Simple, working and reusable. Don't know though if is better to make it a protocol with extension and override in needed places.
  • mfaani
    mfaani about 6 years
    I've never used class var. What's the difference of doing that and shared let? I know their different. Just not sure how!
  • abhimuralidharan
    abhimuralidharan about 6 years
    I just made a computed variable that can be called on a class type directly. You can also use static which is better in this case. What do you mean by shared let?
  • Sujal
    Sujal about 6 years
    And does the reachabilityManager need to be deinitialised in deint() ?
  • Parth Adroja
    Parth Adroja about 6 years
    @Sujal Depends on your use case if you want it into whole application then not needed as you would declare in AppDelegate. If your use case is single shot then you can deinit NetworkReachabilityManager.
  • Ted
    Ted over 5 years
    Do NOT use Reachability to determine if a network request should be sent. You should ALWAYS send it. ref: github.com/Alamofire/Alamofire/blob/master/Documentation/…
  • Khadija Daruwala
    Khadija Daruwala over 5 years
    Everytime i call this function for the first time it gives .reachable true no matter what the state of the internet connect is
  • Anuran Barman
    Anuran Barman about 5 years
    This actually does not work. This just checks whether mobile data or wifi is or or not. It does not check whether the "actual internet" is available or not. Create a hotspot without internet. it will say its connected.
  • Derence
    Derence about 5 years
    Out of all the many answers on the internet, this is the one that worked for me. (Note, that it doesn't work perfectly in the simulator, but on an actual phone it works perfectly.)
  • Lukasz D
    Lukasz D over 2 years
    Show how to switch AFError to get No internet one only