使用Apple的Reachability在Swift中检查远程服务器的可达性

我正在开发用Swift编写的iOS应用程序,它与本地networking上的HTTP服务器进行通信,并使用Apple的Reachability类来确定运行HTTP服务器的远程机器是否在线。 代码如下:

... let RemoteHost: String = "192.168.178.130" var RemoteReachability: Reachability! = nil var RemoteIsReachable: Bool = false init() { super.init() self.RemoteReachability = Reachability(hostName: self.RemoteHost) NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name: kReachabilityChangedNotification, object: self.RemoteReachability) self.RemoteReachability.startNotifier() self.RemoteIsReachable = (self.RemoteReachability.currentReachabilityStatus().value == ReachableViaWiFi.value) } func reachabilityChanged(notification: NSNotification) { let ReachabilityInst: Reachability = notification.object as Reachability self.RemoteIsReachable = (ReachabilityInst.currentReachabilityStatus().value == ReachableViaWiFi.value) } 

问题是无论远程机器是在线还是离线,

 (ReachabilityInst.currentReachabilityStatus().value == ReachableViaWiFi.value) 

只要我连接到Wifinetworking,总是这样。 但是,当我closuresWifi时,结果是错误的,而不是真实的。 我在这里做错了什么,或者Reachability类与Swift / xCode 6 Beta不兼容? 我也试过这个:

 (ReachabilityInst.currentReachabilityStatus() == ReachableViaWiFi) 

但是,这导致xCode告诉我:“无法find接受提供参数的'=='的重载,即使这两个参数都是'NetworkStatus'types。

提前致谢。

你使用的Reachability类是基于苹果的SCNetworkReachability类,它不是你所期望的。 从SCNetworkReachability文档 :

当应用程序发送到networking堆栈中的数据包可以离开本地设备时,认为远程主机是可访问的。 可达性不保证数据包实际上会被主机接收。

所以它不是build立在testing远程主机是否实际在线的基础上的,只是(1)当前的networking设置是否允许尝试到达它;(2)是通过什么方法。 一旦确定networking处于活动状态,您需要尝试连接以查看远程主机是否已启动并正在运行。


注意:这个testing:

 (ReachabilityInst.currentReachabilityStatus().value == ReachableViaWiFi.value) 

是正确的方法来检查 – 由于某种原因NetworkStatus是没有NS_ENUMmacros创build的less数苹果枚举之一 。

迅速,

关于苹果https://developer.apple.com/library/ios/samplecode/Reachability/Introduction/Intro.html )或tonymillionhttps://github.com/tonymillion/Reachability )提出的可达性实用程序的理解,基本上是一样的是:

你有3个可能的testing:

  • 本地 (可以访问本地networking,但不能上网)
  • extern (可以通过ip地址访问internet)
  • DNS (可以访问互联网,并达到主机名)

您可以通过以下方式启动通知程序来分别testing它们:

 let wifiReachability = Reachability. reachabilityForLocalWiFi() wifiReachability.startNotifier() let internetReachability = Reachability.reachabilityForInternetConnection() hostReachability.startNotifier() let hostReachability = Reachability(hostName:"www.apple.com") hostReachability.startNotifier() 

这会触发一个你可以用这个方法捕获的通知: NSNotificationCenter.defaultCenter()。addObserver()

所以要使用它们,你可以做这样的事情:

在你的appDelegate中创build一个函数来实例化通知器:

 func startReachabilityTest() { // Allocate a reachability object to test internet access by hostname let reach = Reachability(hostName: "www.apple.com") // Tell the reachability that we DON'T want to be reachable on 3G/EDGE/CDMA //reach.reachableOnWWAN = false reach.startNotifier() } 

然后你可以在appDelegate的didFinishLaunchingWithOptions中调用它:

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { self.startReachabilityTest(); } 

如果要在任何viewController中捕获事件,只需将此行添加到viewDidLoad:

 override func viewDidLoad() { // Here we set up a NSNotification observer. The Reachability that caused the notification // is passed in the object parameter NSNotificationCenter.defaultCenter().addObserver( self, selector: "reachabilityChanged:", name: kReachabilityChangedNotification, object: nil) } 

并添加这个方法来对事件作出反应:

 func reachabilityChanged(notice: NSNotification) { println("reachability changed") let reach = notice.object as? Reachability if let remoteHostStatus = reach?.currentReachabilityStatus() { if remoteHostStatus == NetworkStatus.NotReachable { println("not reachable") } else { println("reachable") } } } 

你也可以通过在didFinishLaunchingWithOptions中添加NSNotificationCenter.defaultCenter()。addObserver()来捕获appDelegate中的事件,然后在其中添加reachabilityChanged(注意:NSNotification)

啊,还要注意,你可以通过添加下面的代码,很容易地向cocoapods添加可达性类:

 pod 'Reachability', '~> 3.2' 

在命令行安装pod后,将pod文件添加到xxx-Bridging-Header.h头文件(其中xxx是应用程序的名称):

 #import <Reachability/Reachability.h> 

如果您的项目中没有桥接头,则可以按照以下教程进行操作: http : //www.learnswiftonline.com/getting-started/adding-swift-bridging-header/

不需要添加由pod依赖项添加的systemConfiguration.framework。

注意:模拟器中的可达性不能正常工作

希望这个帮助!

如果你正在寻找一个Swift实现苹果的Reachability类,你可以看看这个:

http://github.com/ashleymills/Reachability.swift

这是一个下课,使用通知和closures。

它适用于iOS和OS X,并支持Cocoapod / Carthage。

祝你好运!