2013-02-24 71 views

回答

5

不是我所知。我將使用CoreWLAN獲取系統上所有WiFi接口的列表,然後使用SystemConfiguration框架監視其狀態。

這裏的一個命令行示例(錯誤檢查細微消隱,需要ARC):

#import <Foundation/Foundation.h> 
#import <CoreWLAN/CoreWLAN.h> 
#import <SystemConfiguration/SystemConfiguration.h> 

void wifi_network_changed(SCDynamicStoreRef store, CFArrayRef changedKeys, void *ctx) 
{ 
    [(__bridge NSArray *)changedKeys enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) 
    { 
    /* Extract the interface name from the changed key */ 
    NSString *ifName = [key componentsSeparatedByString:@"/"][3]; 
    CWInterface *iface = [CWInterface interfaceWithName:ifName]; 

    NSLog(@"%@ status changed: current ssid is %@, security is %ld", 
      ifName, iface.ssid, iface.security); 
    }]; 
} 

int main(int argc, char *argv[]) 
{ 
    /* Get a list of all wifi interfaces, and build an array of SCDynamicStore keys to monitor */ 
    NSSet *wifiInterfaces = [CWInterface interfaceNames]; 
    NSMutableArray *scKeys = [[NSMutableArray alloc] init]; 
    [wifiInterfaces enumerateObjectsUsingBlock:^(NSString *ifName, BOOL *stop) 
    { 
    [scKeys addObject: 
     [NSString stringWithFormat:@"State:/Network/Interface/%@/AirPort", ifName]]; 
    }]; 

    /* Connect to the dynamic store */ 
    SCDynamicStoreContext ctx = { 0, NULL, NULL, NULL, NULL }; 
    SCDynamicStoreRef store = SCDynamicStoreCreate(kCFAllocatorDefault, 
               CFSTR("myapp"), 
               wifi_network_changed, 
               &ctx); 

    /* Start monitoring */ 
    SCDynamicStoreSetNotificationKeys(store, 
            (__bridge CFArrayRef)scKeys, 
            NULL); 

    CFRunLoopSourceRef src = SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault, store, 0); 
    CFRunLoopAddSource([[NSRunLoop currentRunLoop] getCFRunLoop], 
        src, 
        kCFRunLoopCommonModes); 
    [[NSRunLoop currentRunLoop] run]; 
} 
+0

這很好,只需要確保適當的框架被添加到XCode中。 – johndbritton 2013-02-28 07:07:02

+0

具有鍵/屬性的列表在此處描述:https://developer.apple.com/library/content/documentation/Networking/Conceptual/SystemConfigFrameworks/SC_UnderstandSchema/SC_UnderstandSchema.html「系統配置編程指南」「系統配置架構」 – 2017-11-21 14:58:05

3

只要拿着打開一個CWInterface,可以使用CWLinkDidChangeNotification等通知。在以下代碼中,i_interfaces是存儲CWInterface數組的ivar,應在開始時調用monitorWifi,listInterfaces列出接口值,並且每當有任何更改時調用handleInterfaceNotification。

請注意,當接口未連接時,iface.ssid/iface.bssid將爲零。

另請注意,由於各種通知,每次連接/斷開連接都會多次調用handleInterfaceNotification。

此代碼來大部分來自NSNotification troubles

-(void) listInterfaces; 
{ 
    NSLog(@"listInterfaces"); 
    [i_interfaces enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) 
    { 
     CWInterface *iface = obj; 
     NSLog(@"iface %@, SSID %@, BSSID %@", iface, iface.ssid, iface.bssid); 
    }]; 
} 


-(void) handleInterfaceNotification:(NSNotification*) notification; 
{ 
    NSLog(@"Notification Received"); 
    [self listInterfaces]; 
} 

- (void) monitorWifi; 
{ 
    NSLog(@"monitorWifi"); 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterfaceNotification:) name:CWModeDidChangeNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterfaceNotification:) name:CWSSIDDidChangeNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterfaceNotification:) name:CWBSSIDDidChangeNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterfaceNotification:) name:CWCountryCodeDidChangeNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterfaceNotification:) name:CWLinkDidChangeNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterfaceNotification:) name:CWPowerDidChangeNotification object:nil]; 

    NSMutableArray* ifaces = [NSMutableArray new]; 
    NSSet *wifiInterfaces = [CWInterface interfaceNames]; 
    [wifiInterfaces enumerateObjectsUsingBlock:^(NSString *ifName, BOOL *stop) 
    { 
     CWInterface *iface = [CWInterface interfaceWithName:ifName]; 
     if (iface) { 
      [ifaces addObject:iface]; 
     } 
    }]; 
    i_interfaces = ifaces; 

    [self listInterfaces]; 
} 
0

高度讚賞。我需要從Swift這樣做,所以這裏有一些Swift代碼讓你開始:

func callback(store: SCDynamicStore, changedKeys: CFArray, 
       context: UnsafeMutableRawPointer?) -> Void { 
    // Do the magic 
} 

// Connect to the store 
guard let store = SCDynamicStoreCreate(nil, "myapp" as CFString, callback, nil) else { 
    print("Could not connect to store") 
    abort() 
} 

// Setup the notification mechanism for any IPv4 event 
var keys = [CFString]() 
keys.append("State:/Network/Global/IPv4" as CFString) 
SCDynamicStoreSetNotificationKeys(store, keys as CFArray, nil) 

// Go into the loop 
let runloop = SCDynamicStoreCreateRunLoopSource(nil, store, 0) 
let currentLoop = RunLoop.current.getCFRunLoop() 
let modes = CFRunLoopMode.commonModes 
CFRunLoopAddSource(currentLoop, runloop, modes) 
RunLoop.current.run() 
相關問題