8

これは微調整用であるため、ターゲットはジェイルブレイクされたデバイスであり、アプリストアではありません。私はさまざまなメソッドをフックしようとしましたSBWiFiManagerが、wifiの強度が(非常に継続的に)変化したとき、またはネットワークが変化した後かなり遅れて呼び出されます。

Wi-Fiネットワークが変更されたときに通知(またはフックする別の方法)を取得する他の方法はありますか?

パブリックAPIを使用して現在のSSIDを取得できることはわかっていますが、変更されたときに通知する必要があります。

4

2 に答える 2

17

com.apple.system.config.network_changeこれを行う1つの方法は、CoreFoundationDarwin通知センターからイベントをリッスンすることです。

イベントに登録する:

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                NULL, // observer
                                onNotifyCallback, // callback
                                CFSTR("com.apple.system.config.network_change"), // event name
                                NULL, // object
                                CFNotificationSuspensionBehaviorDeliverImmediately);

サンプルのコールバックは次のとおりです。

static void onNotifyCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
    NSString* notifyName = (NSString*)name;
    // this check should really only be necessary if you reuse this one callback method
    //  for multiple Darwin notification events
    if ([notifyName isEqualToString:@"com.apple.system.config.network_change"]) {
        // use the Captive Network API to get more information at this point
        //  https://stackoverflow.com/a/4714842/119114
    } else {
        NSLog(@"intercepted %@", notifyName);
    }
}

たとえば、Captive Network APIを使用して現在のSSIDを取得する方法については、別の回答へのリンクを参照してください。

私がこれをテストした電話はジェイルブレイクされていますが(iOS 6.1)、これが正しく機能するためにジェイルブレイクが必要だとは思わないことに注意してください。確かに、通常のサンドボックス領域の外にアプリをインストールする必要はありません(/var/mobile/Applications/*)。

PS私はこれを徹底的にテストしていないので、このイベントが検知を引き起こすかどうかを知ることができません(ネットワーク変更の定義に基づく)。ただし、このイベントが発生するたびに、最後のネットワークのSSIDに等しい状態変数を格納し、それを現在のSSIDと比較するだけで十分に簡単です。

于 2013-02-15T09:00:19.937 に答える
3

SWIFT4.1バージョン

この関数を使用してReachabilityクラスを拡張しました。

let notificationName = "com.apple.system.config.network_change"

func onNetworkChange(_ name : String) {
    if (name == notificationName) {
        // Do your stuff
        print("Network was changed")
    }
}

func registerObserver() {
    let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), observer,
                                    { (nc, observer, name, _, _) -> Swift.Void in
                                        if let observer = observer, let name = name {
                                            let instance = Unmanaged<Reachability>.fromOpaque(observer).takeUnretainedValue()
                                            instance.onNetworkChange(name.rawValue as String)
                                        } },
                                    notificationName as CFString, nil, .deliverImmediately)
}

func removeObserver() {
    let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
    CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), observer, nil, nil)
}

initにオブザーバーを登録し、deinitに削除します。残念ながら、正確に何が変更されたかについての追加情報はありませんが、たとえば現在のSSIDをテストする機会があります。これが誰かに役立つことを願っています)

于 2018-05-04T15:20:26.523 に答える