如何检查alamofire中的互联网连接?

问题描述 投票:20回答:8

我使用下面的代码在服务器中发出HTTP请求。现在我想知道它是否连接到互联网。以下是我的代码

  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))
    }
ios swift alamofire reachability
8个回答
71
投票

对于swift 3.1和Alamofire 4.4,我创建了一个名为Connectivity的快速类。根据您的需要,使用NetworkReachabilityManagerAlamofire类和configureisConnectedToInternet()方法。

import Foundation
import Alamofire

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

用法:

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

编辑:由于swift鼓励计算属性,您可以更改上面的函数,如:

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

并使用它像:

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

18
投票

斯威夫特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
            }

        }
    })

使用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")
}

13
投票

对于Swift 3/4,

在Alamofire,有一个名为NetworkReachabilityManager的类,可用于观察或检查互联网是否可用。

let reachabilityManager = NetworkReachabilityManager()

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

在这里,每次互联网状态发生变化时,都会调用监听器。你可以按照自己的意愿处理它。


2
投票

如果你去NetworkReachabilityManager.swift你会看到这个

///网络当前是否可访问public var isReachable:Bool {return isReachableOnWWAN || isReachableOnEthernetOrWiFi}

所以我在我的APIhandlerClass中写了这个

import AlamofireNetworkActivityIndicator

private let manager = NetworkReachabilityManager(host: "www.apple.com")

func isNetworkReachable() -> Bool {
    return manager?.isReachable ?? false
}

所以这告诉我网络的状态。


1
投票
  func isConnectedToNetwork()-> Bool {

    var zeroAddress = sockaddr_in()
    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)
        }
    }
    //Commented code only work upto iOS Swift 2.3
    //    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
    //
    //        SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
    //    }

    var flags = SCNetworkReachabilityFlags()
    if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
        return false
    }
    let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
    let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
    return (isReachable && !needsConnection)
}
    // Call api method
    func callApi(){
        if isConnectedToNetwork() {  // Network Connection status
            // Call your request here
        }else{
            //"Your Internet connection is not active at this time."
        }
    }

0
投票

如果Alamofire.upload结果返回成功,则下面是在上传图像时检查互联网可用性的方法:

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)

                }

            }

0
投票

使用RequestAdapter类的alamofire并在没有互联网连接时抛出错误

class RequestInterceptor : RequestAdapter{
func adapt(_ urlRequest: URLRequest) throws -> URLRequest {

    let reachable = NetworkReachabilityManager()?.isReachable ?? false
    if !reachable{
        throw NSError.NoInternet
    }
    var nUrlRequest = urlRequest
    // modify request if needed 
    return nUrlRequest
   }
}

extension NSError  {

static func createWithLocalizedDesription(withCode code:Int = 204,localizedDescription:String) -> NSError{
    return  NSError(domain: "<your bundle id>", code:code, userInfo: [NSLocalizedDescriptionKey : localizedDescription])
}
static var NoInternet : NSError {
    return createWithLocalizedDesription(withCode: -1009,localizedDescription:"Please check your internet connection")
}

}

现在将适配器设置为Alamofire Session Manager

let sessionManager = Alamofire.SessionManager(configuration: configuration)

sessionManager.adapter = RequestInterceptor()

现在每次创建Alamofire请求时,都会捕获DataResponse中的错误。这种机制对所有请求都是通用的


0
投票

一般情况下,如果您可以从实际呼叫中获取互联网离线信息,则其优于可达性。您可以确定实际的API调用已失败,因为互联网已关闭。如果你在调用API之前测试可达性并且它失败了那么你所知道的是,当测试完成后互联网处于脱机状态(或Apple已关闭)时,你不知道当你拨打电话时互联网将是离线。您可能认为在可达性调用返回后几毫秒,或者您检索了存储的值,但这实际上是非确定性的。在可达性在其闭包中返回其值之前,操作系统可能已经安排了一些任意数量的线程,或者更新了您正在存储的全局数据。

可达性在历史上一直存在自己的代码中的错误。

这并不是说您不应该使用alamofire的NetworkReachabilityManager来更改UI,收听它并更新所有UI组件。

但是如果您有理由调用API,那么在该API层上,可达性测试是多余的,或者可能会导致一些微妙的错误。

© www.soinside.com 2019 - 2024. All rights reserved.