2017-01-11 27 views
8

Chcę wykryć, kiedy sieć zmienia się z Ethernet na Wi-Fi (lub Wi-Fi na Ethernet). Chcę mieć obserwatora, który powiadomi mnie o tej zmianie.Wykryj zmianę sieci Ethernet/WiFi

osiągalność nie jest wystarczająco dobra - to zawsze zwraca ReachableViaWiFi dla obu przypadków.

PS - Było kilka pytań dotyczących tego tematu wcześniej, ale żaden z nich nie ma dobrej odpowiedzi, a ponieważ te pytania są bardziej niż rok, może ktoś już dowiedzieć się, jak to zrobić

+1

Co jeśli jesteś podłączony do obu? – Sulthan

+0

Możesz rozważyć framework CoreWLAN, jeśli programujesz na macOS – frank

Odpowiedz

2

You mógł uruchomić skrypt bash pod launchd, który monitoruje interesujące Cię interfejsy i uruchamia coś po zmianie.

Wypowiedz połączenie przewodowe jest en0, można uruchomić:

./netmon en0 

Zapisz ten skrypt jako netmon i uczynić go wykonywalnym z chmod +x netmon

#!/bin/bash 
interface=$1 

# Get current status of interface whose name is passed, e.g. en0 
status(){ 
    ifconfig $1 | awk '/status:/{print $2}' 
} 

# Monitor interface until killed, echoing changes in status 
previous=$(status $interface) 
while :; do 
    current=$(status $interface) 
    if [ $current != $previous ]; then 
     echo $interface now $current 
     previous=$current 
    fi 
    sleep 5 
done 
+0

Dzięki, ale chcę włączyć wykrywanie wifi/ethernet w mojej aplikacji, więc gdy użytkownik uruchomi aplikację, aplikacja otrzyma powiadomienia o zmianie interfejsu i wykona jakąś czynność . – Roee84

+0

Więc zacznij nowy wątek, który uruchamia mój skrypt i przeczytaj jego wyniki i postępuj zgodnie z nimi. –

5

Można uzyskać dostęp do ustawień sieciowych systemu przez moduł SystemConfiguration, który pomaga uzyskać dostęp do preferencji systemowych, które obecnie znajdują się w domyślnej lokalizacji /Library/Preferences/SystemConfiguration/preferences.plist.

Od tego czasu możesz otrzymywać powiadomienia od SCDynamicStore przez SCDynamicStoreNotifyValue(_:_:) lub pobrać wartość przez SCDynamicStoreCopyValue(_:_:).

Przykład bezpośrednio odnośnika aktualną podstawową usługę sieciową:

var store = SCDynamicStoreCreate(nil, "Example" as CFString, nil, nil) 
var global = SCDynamicStoreCopyValue(store, "State:/Network/Global/IPv4" as CFString)! 

var pref = SCPreferencesCreate(nil, "Example" as CFString, nil) 
var service = SCNetworkServiceCopy(pref!, global["PrimaryService"] as! CFString) 
var interface = SCNetworkServiceGetInterface(service!) 

SCNetworkInterfaceGetInterfaceType(interface!) /// Optional("IEEE80211") -> Wi-Fi 

Albo stworzyć sklep dynamiczny z zwrotnego i ustawić klawisze powiadomień otrzymać informację, jak każdej usługi sieciowej podstawowy czas zmienia zgłoszenie będzie ogień:

var callback: SCDynamicStoreCallBack = { (store, _, _) in 
    /* Do anything you want */ 
} 
var store = SCDynamicStoreCreate(nil, "Example" as CFString, callback, nil) 
SCDynamicStoreSetNotificationKeys(store!, ["State:/Network/Global/IPv4"] as CFArray, nil) 
+0

Dzięki, ale chcę włączyć wykrywanie wifi/ethernet w mojej aplikacji, więc gdy użytkownik uruchomi aplikację, aplikacja otrzyma powiadomienia o zmianie interfejsu i wykona jakąś czynność. – Roee84

+0

@ Roee84 Mam zaktualizowaną odpowiedź, aby dołączyć przykłady powiadomień :) – Legendecas