引入
#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網(wǎng)絡(luò)框架
#import <NetworkExtension/NetworkExtension.h>
NS_ASSUME_NONNULL_BEGIN
///WiFi
@interface WiFiManager : NSObject
///wifi是否開啟
+ (BOOL)isWiFiEnabled;
/// 打開wifi設(shè)置界面
+ (void)openWiFiSetting;
///獲取當(dāng)前連接的wifi信息
+ (NSDictionary *)getCurrentConnectionWiFiInfo;
///獲取wifi列表
+ (NSMutableArray *)getWiFiList;
///連接指定WiFi
/// @param cmd 命令
/// @param network 網(wǎng)絡(luò)
/// @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)錯(cuò)誤:沒有以字符串?dā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)錯(cuò)誤:\(接口)沒有信息
// print("System error: \(interface) has no information")
// return false
// }
// guard let SSIDDict = (unwrappedCFDictionaryForInterface as NSDictionary) as? [String: AnyObject] else {
// //系統(tǒng)錯(cuò)誤:接口信息不是字符串鍵控字典
// 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, *)) {
//用戶明確拒絕安岂,可以彈窗提示用戶到設(shè)置中手動(dòng)打開權(quán)限
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
NSLog(@"User has explicitly denied authorization for this application, or location services are disabled in Settings.");
//使用下面接口可以打開當(dāng)前應(yīng)用的設(shè)置頁面
//[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
return nil;
}
CLLocationManager* cllocation = [[CLLocationManager alloc] init];
if(![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
//彈框提示用戶是否開啟位置權(quán)限
[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為網(wǎng)絡(luò)接口物理地址凑阶,一般指電腦網(wǎng)卡的物理地址
///獲取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;
}
///當(dāng)前設(shè)備的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信號強(qiáng)度: %f\nCommandType:%ld\n---------------------------\n\n", network.SSID, network.BSSID, network.signalStrength, (long)cmd.commandType];
NSLog(@"%@", wifiInfoString);
// 檢測到指定 WiFi 可設(shè)定密碼直接連接
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 會返回一個(gè) 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;
}
/// 打開無線局域網(wǎng)設(shè)置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:信號強(qiáng)度, cmd:命令類型
NSDictionary *mDic = @{@"NEHotspotHelperCommand":cmd, @"NEHotspotNetwork":network, @"SSID":network.SSID,@"BSSID":network.BSSID, @"signalStrength": @(network.signalStrength), @"commandType":@((long)cmd.commandType)};
[list addObject:mDic];
}
}
}];
// 注冊成功 returnType 會返回一個(gè) Yes 值环形,否則 No
NSLog(@"3.Result: %@", returnType == YES ? @"Yes" : @"No");
return list;
}
///當(dāng)前連接的wifi信息
+ (NSDictionary *)getCurrentConnectionWiFiInfo
{
NSDictionary *currentWifiInfo = nil;
// 獲取當(dāng)前的interface 數(shù)組
CFArrayRef currentInterfaces = CNCopySupportedInterfaces();
if (!currentInterfaces) {
return currentWifiInfo;
}
// 類型轉(zhuǎn)換总寻,將CF對象汗销,轉(zhuǎn)為NS對象犹褒,同時(shí)將該對象的引用計(jì)數(shù)交給 ARC 管理
NSArray *interfaces = (__bridge_transfer NSArray *)currentInterfaces;
if (interfaces.count >0) {
for (NSString *interfaceName in interfaces) {
// 轉(zhuǎn)換類型,不改變引用計(jì)數(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 網(wǎng)絡(luò)
/// @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