OC-WiFi

引入

#import <ifaddrs.h>
#import <net/if.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#import <CoreLocation/CoreLocation.h>

info.plist

Privacy - Location Always Usage Description
Privacy - Location When In Use Usage Description
//
//  WiFiManager.h
//  SmartPrint
//
//  Created by mac on 2021/7/11.
//

#import <Foundation/Foundation.h>
///wifi網絡框架
#import <NetworkExtension/NetworkExtension.h>

NS_ASSUME_NONNULL_BEGIN

///WiFi
@interface WiFiManager : NSObject

///wifi是否開啟
+ (BOOL)isWiFiEnabled;
/// 打開wifi設置界面
+ (void)openWiFiSetting;
///獲取當前連接的wifi信息
+ (NSDictionary *)getCurrentConnectionWiFiInfo;
///獲取wifi列表
+ (NSMutableArray *)getWiFiList;

///連接指定WiFi
/// @param cmd 命令
/// @param network 網絡
/// @param password wifi密碼
+ (void)connectWiFiforCmd:(NEHotspotHelperCommand *)cmd network:(NEHotspotNetwork *)network  password:(NSString *)password;

///斷開指定WiFi
+ (void)disconnectWiFiforCmd:(NEHotspotHelperCommand *)cmd network:(NEHotspotNetwork *)network  password:(NSString *)password;

+ (NSString *)getWiFiName;

@end

NS_ASSUME_NONNULL_END

//
//  WiFi.m
//  SmartPrint
//
//  Created by mac on 2021/7/11.
//


#import "WiFiManager.h"
#import <UIKit/UIKit.h>
#import <ifaddrs.h>
#import <net/if.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#import <CoreLocation/CoreLocation.h>

@implementation WiFiManager

//
//    func getInterfaces() -> Bool {
//        guard let unwrappedCFArrayInterfaces = CNCopySupportedInterfaces() else {
//            print("this must be a simulator, no interfaces found")
//            //這必須是模擬器,沒有找到接口
//            return false
//        }
//        guard let swiftInterfaces = (unwrappedCFArrayInterfaces as NSArray) as? [String] else {
//            //系統(tǒng)錯誤:沒有以字符串數(shù)組的形式返回
//            print("System error: did not come back as array of Strings")
//            return false
//        }
//        for interface in swiftInterfaces {
//            //查找\(接口)的SSID信息
//            print("Looking up SSID info for \(interface)") // en0
//            guard let unwrappedCFDictionaryForInterface = CNCopyCurrentNetworkInfo(interface as CFString) else {
//                //系統(tǒng)錯誤:\(接口)沒有信息
//                print("System error: \(interface) has no information")
//                return false
//            }
//            guard let SSIDDict = (unwrappedCFDictionaryForInterface as NSDictionary) as? [String: AnyObject] else {
//                //系統(tǒng)錯誤:接口信息不是字符串鍵控字典
//                print("System error: interface information is not a string-keyed dictionary")
//                return false
//            }
//            for d in SSIDDict.keys {
//                //打印ssid
//                print("\(d): \(SSIDDict[d]!)")
//            }
//        }
//        return true
//    }
    
    
//    func getWifiName() -> String? {
//
//   let interfaces: CFArray! = CNCopySupportedInterfaces()
//
//   if interfaces == nil { return nil }
//
//    let if0: UnsafePointer? = CFArrayGetValueAtIndex(interfaces, 0)
//
//    if if0 == nil { return nil }
//
//   let interfaceName: CFStringRef = unsafeBitCast(if0!, CFStringRef.self)
//
//    let dictionary = CNCopyCurrentNetworkInfo(interfaceName) as NSDictionary?
//
//    if dictionary == nil { return nil }
//
//    return dictionary?[kCNNetworkInfoKeySSID as String] as? String
//
//    }


+ (NSString *)getWiFiName {
    if (@available(iOS 13.0, *)) {
        //用戶明確拒絕,可以彈窗提示用戶到設置中手動打開權限
        if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
            NSLog(@"User has explicitly denied authorization for this application, or location services are disabled in Settings.");
            //使用下面接口可以打開當前應用的設置頁面
            //[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
            return nil;
        }
        CLLocationManager* cllocation = [[CLLocationManager alloc] init];
        if(![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
            //彈框提示用戶是否開啟位置權限
            [cllocation requestWhenInUseAuthorization];
            usleep(50);
            //遞歸等待用戶選選擇
            //return [self getWifiSsidWithCallback:callback];
        }
    }
    NSString *wifiName = nil;
    CFArrayRef wifiInterfaces = CNCopySupportedInterfaces();
    if (!wifiInterfaces) {
        return nil;
    }
    NSArray *interfaces = (__bridge NSArray *)wifiInterfaces;
    for (NSString *interfaceName in interfaces) {
        CFDictionaryRef dictRef = CNCopyCurrentNetworkInfo((__bridge CFStringRef)(interfaceName));
        
        if (dictRef) {
            NSDictionary *networkInfo = (__bridge NSDictionary *)dictRef;
            NSLog(@"network info -> %@", networkInfo);
            wifiName = [networkInfo objectForKey:(__bridge NSString *)kCNNetworkInfoKeySSID];
            CFRelease(dictRef);
        }
    }
    
    CFRelease(wifiInterfaces);
    return wifiName;
}

///獲取SSID --wifi名稱
+ (NSString *)ssid

{
    
    NSString *ssid = @"Not Found";
    
    CFArrayRef myArray = CNCopySupportedInterfaces();
    
    if (myArray != nil) {
        
        CFDictionaryRef myDict = CNCopyCurrentNetworkInfo(CFArrayGetValueAtIndex(myArray, 0));
        
        if (myDict != nil) {
            
            NSDictionary *dict = (NSDictionary*)CFBridgingRelease(myDict);
            
            ssid = [dict valueForKey:@"SSID"];
            
        }
        
    }
    
    return ssid;
    
}

///獲取MAC --MAC為網絡接口物理地址,一般指電腦網卡的物理地址
///獲取macIP
+ (NSString *)bssid

{
    
    NSString *bssid = @"Not Found";
    
    CFArrayRef myArray = CNCopySupportedInterfaces();
    
    if (myArray != nil) {
        
        CFDictionaryRef myDict = CNCopyCurrentNetworkInfo(CFArrayGetValueAtIndex(myArray, 0));
        
        if (myDict != nil) {
            
            NSDictionary *dict = (NSDictionary*)CFBridgingRelease(myDict);
            
            bssid = [dict valueForKey:@"BSSID"];
            
        }
        
    }
    
    return bssid;
    
}



///當前設備的wifi列表
+ (void)queryDeviceWiFiInfoList {
    dispatch_queue_t q = dispatch_queue_create("com.leopardpan.HotspotHelper", 0);
    [NEHotspotHelper registerWithOptions:nil queue:q handler:^(NEHotspotHelperCommand * _Nonnull cmd) {
        if (cmd.commandType == kNEHotspotHelperCommandTypeFilterScanList) {
            for (NEHotspotNetwork *network in cmd.networkList) {
                NSLog(@"SSID = %@",network.SSID);
                NSLog(@"BSSID = %@",network.BSSID);
            }
        }
    }];
}


+ (void)scanWifiInfos{
    NSLog(@"1.Start");
    
    NSMutableDictionary* options = [[NSMutableDictionary alloc] init];
    [options setObject:@"SmartPrint" forKey: kNEHotspotHelperOptionDisplayName];
    dispatch_queue_t queue = dispatch_queue_create("SmartPrint", NULL);
    
    NSLog(@"2.Try");
    BOOL returnType = [NEHotspotHelper registerWithOptions: options queue: queue handler: ^(NEHotspotHelperCommand * cmd) {
        
        NSLog(@"4.Finish");
        NEHotspotNetwork* network;
        if (cmd.commandType == kNEHotspotHelperCommandTypeEvaluate || cmd.commandType == kNEHotspotHelperCommandTypeFilterScanList) {
            // 遍歷 WiFi 列表,打印基本信息
            for (network in cmd.networkList) {
                NSString* wifiInfoString = [[NSString alloc] initWithFormat: @"---------------------------\nSSID: %@\nMac地址: %@\n信號強度: %f\nCommandType:%ld\n---------------------------\n\n", network.SSID, network.BSSID, network.signalStrength, (long)cmd.commandType];
                NSLog(@"%@", wifiInfoString);
                
                // 檢測到指定 WiFi 可設定密碼直接連接
                if ([network.SSID isEqualToString: @"測試 WiFi"]) {
                    [network setConfidence: kNEHotspotHelperConfidenceHigh];
                    [network setPassword: @"123456789"];
                    NEHotspotHelperResponse *response = [cmd createResponse: kNEHotspotHelperResultSuccess];
                    NSLog(@"Response CMD: %@", response);
                    [response setNetworkList: @[network]];
                    [response setNetwork: network];
                    [response deliver];
                }
            }
        }
    }];
    
    // 注冊成功 returnType 會返回一個 Yes 值,否則 No
    NSLog(@"3.Result: %@", returnType == YES ? @"Yes" : @"No");
}


#pragma mark - WiFi
///是否開啟WiFi
+ (BOOL)isWiFiEnabled {
    NSCountedSet * cset = [NSCountedSet new];
    struct ifaddrs *interfaces;
    if(!getifaddrs(&interfaces)){
        for( struct ifaddrs *interface = interfaces; interface; interface = interface->ifa_next) {
            if ( (interface->ifa_flags & IFF_UP) == IFF_UP ) {
                [cset addObject:[NSString stringWithUTF8String:interface->ifa_name]];
            }
        }
    }
    return [cset countForObject:@"awdl0"] > 1 ? YES : NO;
}

/// 打開無線局域網設置FF
+ (void)openWiFiSetting {
    
    NSURL* urlCheck1 = [NSURL URLWithString: @"App-Prefs:root=WIFI"];
    NSURL* urlCheck2 = [NSURL URLWithString: @"prefs:root=WIFI"];
    NSURL* urlCheck3 = [NSURL URLWithString: UIApplicationOpenSettingsURLString];
    
    NSLog(@"Try to open WiFi Setting, waiting...");
    
    if ([[UIApplication sharedApplication] canOpenURL: urlCheck1]) {
        [[UIApplication sharedApplication] openURL:urlCheck1 options:@{} completionHandler:nil];
    } else if ([[UIApplication sharedApplication] canOpenURL: urlCheck2]) {
        [[UIApplication sharedApplication] openURL:urlCheck2 options:@{} completionHandler:nil];
    } else if ([[UIApplication sharedApplication] canOpenURL: urlCheck3]) {
        [[UIApplication sharedApplication] openURL:urlCheck3 options:@{} completionHandler:nil];
    } else {
        NSLog(@"Unable to open WiFi Setting!");
        return;
    }
    
    NSLog(@"Open WiFi Setting successful.");
}

///獲取wifi列表
+ (NSMutableArray *)getWiFiList {
    NSLog(@"1.Start");
    
    //SmartPrint -> BundleIdentifier
    NSMutableDictionary* options = [[NSMutableDictionary alloc] init];
    [options setObject:@"SmartPrint" forKey: kNEHotspotHelperOptionDisplayName];
    dispatch_queue_t queue = dispatch_queue_create("SmartPrint", NULL);
    
    NSLog(@"2.Try");
    NSMutableArray *list = [@[] mutableCopy];
    BOOL returnType = [NEHotspotHelper registerWithOptions: options queue: queue handler: ^(NEHotspotHelperCommand * cmd) {
        
        NSLog(@"4.Finish");
        NEHotspotNetwork* network;
        if (cmd.commandType == kNEHotspotHelperCommandTypeEvaluate || cmd.commandType == kNEHotspotHelperCommandTypeFilterScanList) {
            //遍歷 WiFi 列表,打印基本信息
            for (network in cmd.networkList) {
                //SSID:wifi名稱, BSSID:Mac地址, signalStrength:信號強度, cmd:命令類型
                NSDictionary *mDic = @{@"NEHotspotHelperCommand":cmd, @"NEHotspotNetwork":network, @"SSID":network.SSID,@"BSSID":network.BSSID, @"signalStrength": @(network.signalStrength), @"commandType":@((long)cmd.commandType)};
                [list addObject:mDic];
            }
        }
    }];
    // 注冊成功 returnType 會返回一個 Yes 值,否則 No
    NSLog(@"3.Result: %@", returnType == YES ? @"Yes" : @"No");
    return  list;
}

///當前連接的wifi信息
+ (NSDictionary *)getCurrentConnectionWiFiInfo
{
    NSDictionary *currentWifiInfo = nil;
    // 獲取當前的interface 數(shù)組
    CFArrayRef currentInterfaces = CNCopySupportedInterfaces();
    if (!currentInterfaces) {
        return currentWifiInfo;
    }
    // 類型轉換,將CF對象,轉為NS對象,同時將該對象的引用計數(shù)交給 ARC 管理
    NSArray *interfaces = (__bridge_transfer NSArray *)currentInterfaces;
    if (interfaces.count >0) {
        for (NSString *interfaceName in interfaces) {
            // 轉換類型,不改變引用計數(shù)
            CFDictionaryRef dictRef = CNCopyCurrentNetworkInfo((__bridge CFStringRef)(interfaceName));
            if (dictRef) {
                NSDictionary *networkInfo = (__bridge_transfer NSDictionary *)dictRef;
                NSString *SSID = [networkInfo objectForKey:(__bridge_transfer NSString *)kCNNetworkInfoKeySSID];
                NSString *BSSID = [networkInfo objectForKey:(__bridge_transfer NSString *)kCNNetworkInfoKeyBSSID];
                NSData *SSIDDATA = [networkInfo objectForKey:(__bridge_transfer NSData *)kCNNetworkInfoKeySSIDData];
                currentWifiInfo = @{@"SSID":SSID,
                                    @"BSSID":BSSID,
                                    @"SSIDDATA":SSIDDATA};
                
            }
        }
    }
    NSLog(@"currentWifiInfo = %@",currentWifiInfo);
    return currentWifiInfo;
}


///連接指定WiFi
/// @param cmd 命令
/// @param network 網絡
/// @param password wifi密碼
+ (void)connectWiFiforCmd:(NEHotspotHelperCommand *)cmd network:(NEHotspotNetwork *)network password:(NSString *)password
{
        [network setConfidence: kNEHotspotHelperConfidenceHigh];
        [network setPassword: password];
        NEHotspotHelperResponse *response = [cmd createResponse: kNEHotspotHelperResultSuccess];
        NSLog(@"Response CMD: %@", response);
        [response setNetworkList: @[network]];
        [response setNetwork: network];
        [response deliver];
}

///斷開指定WiFi
+ (void)disconnectWiFiforCmd:(NEHotspotHelperCommand *)cmd network:(NEHotspotNetwork *)network password:(NSString *)password {
    [network setConfidence: kNEHotspotHelperConfidenceHigh];
    [network setPassword: password];
    NEHotspotHelperResponse *response = [cmd createResponse: kNEHotspotHelperResultSuccess];
    NSLog(@"Response CMD: %@", response);
    [response setNetworkList: @[network]];
    [response setNetwork: network];
    [response deliver];
}


@end

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容