检查Internet连接可用性?

时间:2015-08-24 15:08:55

标签: ios swift reachability

我只需要在开始与我的iphone应用程序中的服务通信之前检查互联网连接可用性。我使用Swift 1.2和Xcode 6作为我的开发环境......

我刚做了一些研究,发现这个stackoverflow LINK在目标C中。

因此,我试图在SWIFT中找到类似的解决方案,并找到以下链接

https://coderwall.com/p/mhxbpq/checking-for-internet-connection-availability

为了方便起见,该链接中的内容如下......

import Foundation
import SystemConfiguration

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(sizeofValue(zeroAddress))
      zeroAddress.sin_family = sa_family_t(AF_INET)

      let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
        SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)).takeRetainedValue()
      }

      var flags: SCNetworkReachabilityFlags = 0
      if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == 0 {
        return false
      }

      let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0
      let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0

      return (isReachable && !needsConnection) ? true : false
  }

}

并检查这样的连接可用性......

if Reachability.isConnectedToNetwork() 
{
    println("Haz Interwebz!")
}  
else
{
    println("Oh noes! No interwebz!!!")
}

注意:要工作,需要将 SystemConfiguration.framework 添加到项目中(对于“链接的框架和库”)....

所以.... 我的问题是,我对于iOS开发来说还是一个新手,并且不太确定使用这个逻辑来完成它是多么好和可靠。该课程中的大部分内容都完全不清楚,但我所做的小测试效果很好!!!

喜欢听听开发人员对此有何更多体验。

4 个答案:

答案 0 :(得分:12)

我希望今天早上为自己解决同样的问题而且我觉得这个" Reachability" Apple提供的示例代码根本不吸引我(主要是因为手动打开套接字和SystemConfiguration丑陋的API)。

而不是这样,我尝试使用Alamofire(我已经将它作为依赖项)与一个随机的不存在的URL建立一个简单的HTTP连接,并检查我将收到的错误中的值。

Alamofire.request(.GET, "http://superrandomdomainnamethatisnotused.com/superrandompath").responseString {
    (request, response, stringData, error) in

    if let networkError = error {
        if (networkError.code == -1009) {
            println("No Internet \(error)")
        }
    }
}

可以使用任何其他网络库重写此代码。错误-1009与NSURLErrorNotConnectedToInternet相对应,这更令人放心的说法" 您实际上没有连接到互联网"。

另一个好处是,即使您放置了不存在的URL,这也很有效,这意味着即使您有Internet连接,也不必向任何服务器发出成功的HTTP请求。

缺点是块中的代码是异步执行的,这可能会给您带来不便。

答案 1 :(得分:5)

@ Lachezar对 Swift2.x 的回答的改进版本:

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
            }
    }
}

如果您希望在不解析网址的情况下获得网络状态,我建议使用此解决方案:https://stackoverflow.com/a/38646078/706933

答案 2 :(得分:2)

为Swift 5.x编辑:

import SystemConfiguration

public class CheckInternet{

    class func Connection() -> 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
        }


        // Working for Cellular and WIFI
        let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
        let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
        let ret = (isReachable && !needsConnection)

        return ret


    }

}

答案 3 :(得分:0)

Alamofire

我建议听取可达性而不是使用get api。

您可以将以下类添加到您的应用中,并调用MNNetworkUtils.main.isConnected()获取其是否已连接的布尔值。

class MNNetworkUtils {
  static let main = MNNetworkUtils()
  init() {
    manager = NetworkReachabilityManager(host: "google.com")
    listenForReachability()
  }

  private let manager: NetworkReachabilityManager?
  private var reachable: Bool = false
  private func listenForReachability() {
    self.manager?.listener = { [unowned self] status in
      switch status {
      case .notReachable:
        self.reachable = false
      case .reachable(_), .unknown:
        self.reachable = true
      }
    }
    self.manager?.startListening()
  }

  func isConnected() -> Bool {
    return reachable
  }
}

这是一个单身人士课程。每当用户连接或断开网络时,它都会正确覆盖self.reachable为真/假,因为我们开始在单例初始化时监听NetworkReachabilityManager

另外,为了监控可达性,您需要提供一个主机,目前我正在使用google.com随时更改为任何其他主机或其中一个主机(如果需要)。