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