OC-WiFi

2021-07-14  本文已影响0人  ChaosHeart

引入

#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 {
//            //系统错误:没有以字符串数组的形式返回
//            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 {
//                //系统错误:\(接口)没有信息
//                print("System error: \(interface) has no information")
//                return false
//            }
//            guard let SSIDDict = (unwrappedCFDictionaryForInterface as NSDictionary) as? [String: AnyObject] else {
//                //系统错误:接口信息不是字符串键控字典
//                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 数组
    CFArrayRef currentInterfaces = CNCopySupportedInterfaces();
    if (!currentInterfaces) {
        return currentWifiInfo;
    }
    // 类型转换,将CF对象,转为NS对象,同时将该对象的引用计数交给 ARC 管理
    NSArray *interfaces = (__bridge_transfer NSArray *)currentInterfaces;
    if (interfaces.count >0) {
        for (NSString *interfaceName in interfaces) {
            // 转换类型,不改变引用计数
            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

上一篇下一篇

猜你喜欢

热点阅读