Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
286 views
in Technique[技术] by (71.8m points)

ios - Using Apple's Reachability to check remote server reachability in Swift

I'm developing an iOS application written in Swift that communicates with a HTTP server on the local network, and I'm using Apple's Reachability class to determine wether the remote machine running the HTTP server is online or not. Here's the code:

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

The problem is that no matter if the remote machine is online or offline,

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

Is always true, as long as I'm connected to a Wifi network. However, when I turn Wifi off, it results in being false instead of true. Am I doing something wrong here, or is the Reachability class just not compatible with Swift/xCode 6 Beta yet? I've also tried this:

(ReachabilityInst.currentReachabilityStatus() == ReachableViaWiFi)

But that results in xCode telling me "Could not find an overload for '==' that accepts the supplied arguments", even though both appear to be of type 'NetworkStatus'.

Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The Reachability class you're using is based on Apple's SCNetworkReachability class, which doesn't do exactly what you're hoping. From the SCNetworkReachability documentation:

A remote host is considered reachable when a data packet, sent by an application into the network stack, can leave the local device. Reachability does not guarantee that the data packet will actually be received by the host.

So it's not built for testing whether or not the remote host is actually online, just whether (1) the current network settings will allow an attempt to reach it and (2) by what methods. Once you've determined that the network is active you'll need to make an attempt to connect to see if the remote host is actually up and running.


Note: This test:

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

is the correct way to check -- for some reason NetworkStatus is one of the few Apple enumerations created without the NS_ENUM macro.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...