引言
推荐采用本文的方案二:采用MobileWiFi.framework自动连接特定Wi-Fi
方案二的背景: 实现Associate to wifi的,在iOS 版本10 之后,就比较困难,因为苹果将SBWiFiManager 的joinNetwork:password:移除掉;且在iOS10 中SBWiFiManager 的t_manager、t_device、t_currentNetwork 均采用 struct存储,提高了安全性。
因此要实现自动 Associate to wifi 的话,我
从hopper 中看到sb 中使用WiFiManagerClientCreate() 实现连接Wi-Fi,因此就才想到使用MobileWiFi.framework 实现是最佳的捷径
I、 自动连接特定Wi-Fi
1.1 方案一:使用wifiutil工具进行连接Wi-Fi
- 借助wifiutil 控制Wi-Fi的连接(setupwifi)
[%c(SpringBoard) setupwifi];//连接特定Wi-Fi %new + (void) setupwifi{ NSArray* args = @[@"enable-wifi"]; [KNnoZombieRunobjc noZombieRun:@"/usr/bin/wifiutil" withParams:args]; NSArray* args1 = @[@"disassociate"]; [KNnoZombieRunobjc noZombieRun:@"/usr/bin/wifiutil" withParams:args1]; NSArray* args2 = @[@"associate",@"@PHICOMM_08",@"-p",@"password"]; [KNnoZombieRunobjc noZombieRun:@"/usr/bin/wifiutil" withParams:args2]; }
1.2 方案二:MobileWiFi.framework
采用MobileWiFi.framework自动连接特定Wi-Fi
- AirPortSettings
// #import <objc/runtime.h> #import "KNwifiutil.h" #import "KNnoZombieRunobjc.h" @interface WiFiNetwork : NSObject <NSCoding, NSCopying>{ } @end @implementation KNwifiutil // ls -lrt Layout/usr/bin/wifiutil //%new // iphone/tool command line Tool + (void) setupwifi{ NSArray* args = @[@"enable-wifi"]; [KNnoZombieRunobjc Run:@"/usr/bin/wifiutil" withParams:args]; NSArray* args1 = @[@"disassociate"]; [KNnoZombieRunobjc Run:@"/usr/bin/wifiutil" withParams:args1]; NSArray* args2 = @[@"associate",@"@PHICOMM_08",@"-p",@"password"]; [KNnoZombieRunobjc Run:@"/usr/bin/wifiutil" withParams:args2]; } //iOS9-SpringBoard-Headers/System/Library/PreferenceBundles/ //一、AirPortSettings.bundle 可以用来处理Wi-Fi的自动连接 //dlopen("/System/Library/PreferenceBundles/AirPortSettings.bundle/AirPortSettings",RTLD_NOW); //二、VPNPreferences.bundle 可用用来自动处理VPN NSBundle* VPNPreferences = [NSBundle bundleWithPath:@"/System/Library/PreferenceBundles/VPNPreferences.bundle"]; //[VPNPreferences load]; ///System/Library/PreferenceBundles/AirPortSettings.bundle/AirPortSettings +(void)AirPortSettings{ //1、Wi-Fi的打开和关闭 -fno-objc-arc 防止找不到方法报错 [[objc_getClass("SBWiFiManager") sharedInstance] setPowered:YES]; [[objc_getClass("SBWiFiManager") sharedInstance] setWiFiEnabled:YES]; id _wifi = [objc_getClass("SBWiFiManager") sharedInstance]; //2、 NSArray<WiFiNetwork*>* networks = [_wifi availableNetworks];//扫描可用的Wi-Fi NSString *name = @""; NSString *password = @""; for (WiFiNetwork *network in networks) {// 以下代码有待优化 if ([[network name] isEqualToString:name]) {// 连接特定的Wi-Fi if ([network canAttemptJoin]) { } else{// 不能连接就设置对应的密码 [network setPassword:password];// 设置Wi-Fi的密码 } //// [[objc_getClass("SBWiFiManager") sharedInstance] _askToJoinWithID:0]; // -(void)joinNetwork:(id)network password:(id)password; if ([network canAttemptJoin]) {// 代表是可以连接的 [_wifi joinNetwork:network];//连接特定的Wi-Fi } else{ NSLog(@"password error"); } break; } } } @end
1.3 工具方法: OC执行二进制文件
(BOOL) Run:(NSString*) path withParams:(NSArray*)args
#import "KNnoZombieRunobjc.h" #include <spawn.h> @implementation KNnoZombieRunobjc static int knlaunchProcess(const char* path, char** args) { posix_spawnattr_t attr; posix_spawn_file_actions_t fact; posix_spawnattr_init(&attr); posix_spawn_file_actions_init(&fact); char* const environ[2] = {"", NULL}; pid_t pid = 0; posix_spawnp(&pid, path, &fact, &attr, args, environ); return pid; } + (BOOL) Run:(NSString*) path withParams:(NSArray*)args { const char* _path = [path UTF8String]; int n = args ? args.count : 0; char** _args = alloca(sizeof(char*) * (n + 2)); _args[0] = ""; _args[n+1] = NULL; for (int i = 0; i < n; i++) { NSString* arg = args[i]; _args[i+1] = [arg UTF8String]; } pid_t pid = fork(); if (pid < 0) { return NO; } else if (pid == 0) { knlaunchProcess(_path, _args); _exit(0); } waitpid(pid, NULL, 0); return YES; } @end