ローカルネットワーク上のHTTPサーバーと通信するSwiftで記述されたiOSアプリケーションを開発しています。また、HTTPサーバーを実行しているリモートマシンがオンラインかどうかを判断するためにAppleのReachabilityクラスを使用しています。コードは次のとおりです。
...
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)
私がWi-Fiネットワークに接続している限り、常に本当です。ただし、Wifiをオフにすると、trueではなくfalseになります。私はここで何か間違っているのですか、それともReachabilityクラスはまだSwift/xCode 6 Betaと互換性がないのですか?私もこれを試しました:
(ReachabilityInst.currentReachabilityStatus() == ReachableViaWiFi)
しかし、その結果、xCodeは「指定された引数を受け入れる '=='のオーバーロードを見つけることができませんでした」と通知しますが、どちらも 'NetworkStatus'タイプであるように見えます。
前もって感謝します。
使用しているReachabilityクラスは、AppleのSCNetworkReachabilityクラスに基づいています。これは、期待どおりの動作をしません。 SCNetworkReachabilityドキュメント から:
アプリケーションからネットワークスタックに送信されたデータパケットがローカルデバイスを離れることができる場合、リモートホストは到達可能と見なされます。到達可能性は、データパケットが実際にホストによって受信されることを保証するものではありません。
したがって、リモートホストが実際にオンラインであるかどうかをテストするために構築されているのではなく、(1)現在のネットワーク設定がそれに到達する試みを許可するかどうか、および(2)どの方法でアクセスできるかだけです。ネットワークがアクティブであると判断したら、リモートホストが実際に稼働しているかどうかを確認するために接続を試行する必要があります。
注:このテスト:
(ReachabilityInst.currentReachabilityStatus().value == ReachableViaWiFi.value)
は正しいチェック方法です-何らかの理由でNetworkStatus
はいくつかのApple NS_ENUMマクロなしで作成された列挙) の1つです。
Apple( https://developer.Apple.com/library/ios/samplecode/Reachability)が提案する到達可能性ユーティリティについて理解したことについて/Introduction/Intro.html )またはtonymillion( https://github.com/tonymillion/Reachability )基本的に同じです:
あなたは3つの可能なテストがあります:
これで通知機能を開始することにより、それぞれをテストできます。
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に関数を作成します。
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)
}
イベントに反応するこのメソッドmethodを追加します:
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(notice:NSNotification)を追加することもできます。 初期化。
次の行を追加することで、cocoapodsを使用してプロジェクトに到達可能性クラスを簡単に追加できることにも注意してください。
pod 'Reachability', '~> 3.2'
コマンドラインでpod installを実行した後のpodファイルとそれらのファイルに、この行をxxx-Bridging-Headerに追加するだけです.hヘッダーファイル(xxxはアプリの名前です):
#import <Reachability/Reachability.h>
プロジェクトにブリッジヘッダーがない場合は、次のチュートリアルに従ってください。 http://www.learnswiftonline.com/getting-started/adding-Swift-bridging-header/
ポッドの依存関係によってすでに追加されているsystemConfiguration.frameworkを追加する必要はありません。
注:到達可能性はシミュレーターでは正常に機能しません
この助けを願っています!
Appleの到達可能性クラスのSwift実装)を探しているなら、これを見てみることができます:
http://github.com/ashleymills/Reachability.Swift
これはクラスのドロップであり、通知とクロージャを使用しています。
IOSおよびOS Xで動作し、Cocoapod/Carthageをサポートしています。
幸運を!
結合と到達可能性の使用:
import Combine
import Reachability
import os
class ReachabilityStore: ObservableObject {
private var reachability: Reachability
@Published var reachable: Bool = false
@Published var reachableViaWifi: Bool = false
@Published var reachableViaCellular: Bool = false
init() {
reachability = try! Reachability()
reachability.whenReachable = { [weak self] reachability in
guard let self = self else { return }
self.reachable = true
self.reachableViaWifi = reachability.connection == .wifi
self.reachableViaCellular = !self.reachableViaWifi
os_log(
"Reachable via %{public}s",
self.reachableViaWifi ? "WiFi" : "Cellular"
)
}
reachability.whenUnreachable = { [weak self] _ in
guard let self = self else { return }
os_log("Unreachable")
self.reachable = false
self.reachableViaWifi = false
self.reachableViaCellular = false
}
do {
try reachability.startNotifier()
} catch {
os_log("Unable to start reachability notifier.")
}
}
}