美文网首页
更改手机WIFI

更改手机WIFI

作者: 庚妖素 | 来源:发表于2019-12-11 13:14 被阅读0次

前言

最近有一个需求,为了方便用户操作,优化用户体验,我们需要实现在APP内控制WiFi的开关、连上指定的WiFi,以及给这个WiFi设置HTTP代理,经过一番折腾,发现在未越狱的手机下只实现前两个功能,要想给指定WiFi设置系统级的代理目前没有发现什么有效的解决方案,在此记录一下这几天探索的结果。

现状分析

目前只有iOS11以上包含iOS11才可以使用NetworkExtension库中的NEHotspotConfigurationManagerAPI来操作WiFi,通过该API可以连接指定SSID的WIFI,如果没有手动打开系统WIFI开关,则还可以通过它打开系统WIFI开关,该库的有些API是需要像苹果写邮件申请权限的,比如HotspotHelper API权限,这个HotspotHelper权限比较难申请,但此次用的API并不需像某些博客中说的需要写邮件申请HotspotHelper权限,而此次用到底API只需要在Xcode中开启Hotspot configuration普通权限,并且添加依赖库NetworkExtension,iOS11之前我们的做法是通过引导用户手动去操作。通过NEHotspotConfigurationManager来管理热点还需要有一个热点配置对象NEHotspotConfiguration,创建这个对象的苹果提供了一下三种方式。

Network Extension权限问题官网介绍

在2016年11月10日之前要使用 NetworkExtension 框架需要向苹果官方发邮件提供资质,申请权限。

但是在2016年11月10日之后,如果只是使用下面几种功能的话,已经不需要提交邮件申请就可以使用了

App Proxy

Content Filter

Packet Tunnel APIs

但是Network Extension Hotspot Entitlements(HotSpot)这个Wifi热点功能需要邮件申请权限。

权限申请地址:https://developer.apple.com/contact/network-extension

WIFI控制实现方式

在写实现方式之前需要先科普一些WiFi的知识:

目前WIFI常用的加密方式有WEP、WPA/WPA2、TKIP、EAP等。

无线网络的安全性由认证和加密来保证:

1)认证允许只有被许可的用户才能连接到无线网络;

2)加密的目的是提供数据的保密性和完整性(数据在传输过程中不会被篡改)。

常用名字解释

Open Wi-Fi Network:开放式WIFI,没有密码,但连接WIFI后有可能会弹出portal认证网页要求输入账号去认证,这个取决于WIFI提供者提供的策略,如果需要portal认证界面,在iOS端会有45秒左右的连接延迟,这是由于iOS系统WIFI连接的验证策略导致,但是Android能瞬间弹出portal认证界面。

WEP:一种加密标准,该算法已经不安全了。

EAP:全称Extensible Authentication Protocol,是一种支持多种验证方式的协议框架,EAP通常运行在链路层例如PPP和IEEE 802。EAP协议是IEEE 802.1x认证机制的核心,它将实现细节交由附属的EAP Method协议完成,如何选取EAP method由认证系统特征决定,这样实现了EAP的扩展性及灵活性。

WPA/WPA2 Personal Wi-Fi Network:采用WPA/WPA2加密的个人级WIFI。

WPA/WPA2 Enterprise Wi-Fi Network:采用WPA/WPA2加密的企业级WIFI。

HS2.0 Wi-Fi Network:采用HS2.0协议的WIFI。

有关WIFI的认证和加密的详情具体参考文章

了解了上面的名词,我们来看iOS提供的四种WIFI控制方式,通过这四种方式可以实现操作不同加密策略的WIFI。

用于初始化没有密码的开方式WIFI的配置对象,注意ssid的的长度是1~32字符。

-(instancetype)initWithSSID:(NSString *)SSID API_AVAILABLE(ios(11.0))API_UNAVAILABLE(macos,watchos,tvos);

用于初始化一个采用WEP加密或者WPA/WPA2加密的个人级的WiFi配置对象,如果最后一个参数是NO,则采用WEP方式加密,否则采用WPA/WPA2加密,无论是那种加密方式都需要提供指定的ssid和passphrase才能连接上WIFI。

注意passphrase和password是有区别的

密码(password)是一组字母、数字、符号,表示用户的身份。密码一般比较短8/6/6字符,而且密码的复杂性有要求,如不能出现常见的字、词等等。

passphrase类似于密码(password),但passphrase并不是直接使用的,而是通过一定的算法将passphrase转换为用于加密的密钥。Passphrase可以很长,通常为20-30个字符,另外,由于不是直接使用passphrase,所以可以使用容易记忆的句子作为passphrase

/*!

* @method initWithSSID:passphrase:isWEP

* @discussion

*  A designated initializer to instantiate a new NEHotspotConfiguration object.

*  This initializer is used configure either WEP or WPA/WPA2 Personal Wi-Fi Networks.

*

* @param SSID The SSID of the WEP or WPA/WPA2 Personal Wi-Fi Network

* @param passphrase The passphrase credential.

*  For WPA/WPA2 Personal networks: between 8 and 63 characters.

*  For Static WEP(64bit)  : 10 Hex Digits

*  For Static WEP(128bit) : 26 Hex Digits

* @param isWEP YES specifies WEP Wi-Fi Network else WPA/WPA2 Personal Wi-Fi Network

*/-(instancetype)initWithSSID:(NSString*)SSIDpassphrase:(NSString*)passphrase isWEP:(BOOL)isWEPAPI_AVAILABLE(ios(11.0))API_UNAVAILABLE(macos,watchos,tvos);

用于配置一个企业级的WiFi配置对象,EAP类型的WIFI,加密方式采用的是WPA/WPA2,连接此种WiFi iOS系统会弹出一个验证窗口,需要输入用户名和密码。

/*!

* @method initWithSSID:eapSettings

* @discussion

*  A designated initializer to instantiate a new NEHotspotConfiguration object.

*  This initializer is used configure WPA/WPA2 Enterprise Wi-Fi Networks.

*

* @param SSID The SSID of WPA/WPA2 Enterprise Wi-Fi Network

* @param eapSettings EAP configuration

*/-(instancetype)initWithSSID:(NSString*)SSIDeapSettings:(NEHotspotEAPSettings*)eapSettingsAPI_AVAILABLE(ios(11.0))API_UNAVAILABLE(macos,watchos,tvos);

具有HS 2.0和EAP设置的Hotspot 2.0 Wi-Fi网络

/*!

* @method initWithHS20Settings:eapSettings

* @discussion

*  A designated initializer to instantiate a new NEHotspotConfiguration object.

*  This initializer is used configure HS2.0 Wi-Fi Networks.

*

* @param hs20Settings Hotspot 2.0 configuration

* @param eapSettings EAP configuration

*/-(instancetype)initWithHS20Settings:(NEHotspotHS20Settings*)hs20Settings                        eapSettings:(NEHotspotEAPSettings*)eapSettingsAPI_AVAILABLE(ios(11.0))API_UNAVAILABLE(macos,watchos,tvos);

具体代码实现

代码中有详细的注释,需要注意的是NEHotspotConfigurationManager的回调结果不能仅凭error参数来决定,如果连接一个不存在的ssid,errorl也会为空,所以需要结合当前连接的ssid来给出成功与否的判断。

-(void)openSpecialWIFI{if(@available(iOS11.0,*)){// 用代码自动切换到指定的WiFi热点MBProgressHUD*hud=[MBProgressHUD showHUDAddedTo:self.view animated:YES];hud.removeFromSuperViewOnHide=YES;NEHotspotConfiguration*netConfig=nil;if(self.enableEAPSwitch.on){// Extensible Authentication Protocol (EAP) settings for configuring WPA and WPA2 enterprise Wi-Fi networks.NEHotspotEAPSettings*epSettings=[[NEHotspotEAPSettings alloc]init];epSettings.supportedEAPTypes=@[@(NEHotspotConfigurationEAPTypeEAPPEAP)];epSettings.ttlsInnerAuthenticationType=NEHotspotConfigurationEAPTTLSInnerAuthenticationMSCHAP;epSettings.username=self.username.text;epSettings.password=self.pwd.text;netConfig=[[NEHotspotConfiguration alloc]initWithSSID:self.wifiName.text eapSettings:epSettings];//NEHotspotConfiguration *netConfig = [[NEHotspotConfiguration alloc] initWithSSID:self.wifiName.text passphrase:self.wifiPWD.text isWEP:NO];}else{netConfig=[[NEHotspotConfiguration alloc]initWithSSID:self.wifiName.text];}NSLog(@"要连接的WIFI信息:\nWiFi名称:%@\nWiFi密码:%@\nEAP设置:\n用户名:%@\n密码:%@",self.wifiName.text,self.wifiPWD.text,self.username.text,self.pwd.text);/*

            NEHotspotConfiguration可以创建两种形式的WIFI,一种是临时模式joinOnce(默认为NO),另一种是永久模式persistent,

        当使用临时模式时:

            1、临时模式当APP在后台超过15秒就自动断开指定的WIFI了

            2、设备睡眠状态

            3、本APP crash、退出或者卸载

            4、本APP连接了另一个WIFI

            5、用户手动连接了另一个WIFI

            具体参考https://developer.apple.com/documentation/networkextension/nehotspotconfiguration/2887518-joinonce

        */netConfig.joinOnce=NO;// 1、移除网络配置,关闭网络[selfdisconnectWIFI];// 2、打开网络,调用此方法系统会自动弹窗确认[[NEHotspotConfigurationManager sharedManager]applyConfiguration:netConfig completionHandler:^(NSError*_Nullable error){NSString*currentConnectedWifi=[[selfcurrnentConnectedWIFIInfo]objectForKey:@"SSID"]?:@"";if(error||![currentConnectedWifi isEqualToString:self.wifiName.text]){NSLog(@"无法连接热点:%@",error);NSString*msg=@"连接异常!";if(error&&error.code!=13&&error.code!=7){NSLog(@"WIFI连接失败!");msg=[NSString stringWithFormat:@"%@ - 无法连接热点%@",self.wifiName.text,error.localizedDescription];}elseif(error.code==7){// 用户点击了弹出框的取消按钮NSLog(@"已取消");msg=@"您取消了WIFI连接按钮!";}else{NSLog(@"连接的不是当前WIFI");msg=@"WIFI连接失败!";}hud.mode=MBProgressHUDModeText;hud.label.text=msg;[hud showAnimated:YES];[hud hideAnimated:YES afterDelay:1.5f];}else{//连接wifi成功NSLog(@"连接WiFi成功");hud.mode=MBProgressHUDModeText;hud.label.text=[NSString stringWithFormat:@"%@ 连接成功~",self.wifiName.text];[hud showAnimated:YES];[hud hideAnimated:YES afterDelay:1.5f];}// 打印所有已经配置过的WIFI[selfgetAllConfiguredWIFIList];}];}else{// 需要手动去连接WiFiUIAlertController*alertVC=[UIAlertController alertControllerWithTitle:@"提示"message:@"您必须手动连接上指定的WIFI才能使用该功能,请点击右上角查看具体操作!"preferredStyle:UIAlertControllerStyleAlert];UIAlertAction*sureAction=[UIAlertAction actionWithTitle:@"知道了"style:UIAlertActionStyleDefault handler:^(UIAlertAction*_Nonnull action){[selfopenWIFISettingPage];}];[alertVC addAction:sureAction];[selfpresentViewController:alertVC animated:YES completion:^{}];}}

断开指定的已经连接的WIFI,此API只是清除了指定WIFI的配置信息,并不会关闭系统WIFI开关,所有有可能会自动连接上其他已经配置的WIFI。

-(void)disconnectWIFI{[[NEHotspotConfigurationManagersharedManager]removeConfigurationForSSID:self.wifiName.text];}

获取当前连接WIFI的信息,注意iOS12包含iOS12以后如果要获取当前已连接WiFi的信息需要在Xcode开启only need openAccess WIFI informationon capacities

-(NSDictionary*)currnentConnectedWIFIInfo{NSArray*ifs=(__bridge_transfer id)CNCopySupportedInterfaces();NSLog(@"interfaces:%@",ifs);NSDictionary*info=nil;for(NSString*ifnameinifs){info=(__bridge_transfer NSDictionary*)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifname);NSLog(@"%@ => %@",ifname,info);if(info&&[info count])break;}returninfo;}

获取已经配置过(也就是已经被保存过的WIFI)的wifi名称。如果你设置joinOnce为YES,此WIFI在这里就不会被获取。

//获取已经配置过(也就是已经被保存过的WIFI)的wifi名称。如果你设置joinOnce为YES,这里就不会有了-(void)getAllConfiguredWIFIList{[[NEHotspotConfigurationManager sharedManager]getConfiguredSSIDsWithCompletionHandler:^(NSArray<NSString*>*_Nonnull list){NSLog(@"所有已经配置过的WIFI列表~~~ %@",list);}];}

WIFI HotspotHelper

iOS9 苹果提供了获取系统WiFi列表,注意需要手动开启WiFi,从系统settings进入WiFi列表后,回调才起作用,才能获取到WIFI列表,另外此操作需要向Apple申请权限

-(void)getWifiList{// iOS9 之前无法获取WiFi列表if(!([[[UIDevice currentDevice]systemVersion]floatValue]>=9.0))return;// iOS9之后可以获取WiFi列表,对WiFi进行一些操作,比如给指定的WiFi设置密码NSMutableDictionary*options=[[NSMutableDictionary alloc]init];[options setObject:@"点我上网"forKey:kNEHotspotHelperOptionDisplayName];dispatch_queue_t queue=dispatch_queue_create("com.pronetwayXY",NULL);BOOL returnType=[NEHotspotHelper registerWithOptions:options queue:queue handler:^(NEHotspotHelperCommand*cmd){NEHotspotNetwork*network;NSLog(@"COMMAND TYPE:  %ld",(long)cmd.commandType);[cmd createResponse:kNEHotspotHelperResultAuthenticationRequired];if(cmd.commandType==kNEHotspotHelperCommandTypeEvaluate||cmd.commandType==kNEHotspotHelperCommandTypeFilterScanList){NSLog(@"WIFILIST:  %@",cmd.networkList);for(networkincmd.networkList){// NSLog(@"COMMAND TYPE After:  %ld", (long)cmd.commandType);if([network.SSID isEqualToString:@"ssid"]||[network.SSID isEqualToString:@"proict_test"]){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);[network setConfidence:kNEHotspotHelperConfidenceHigh];[network setPassword:@"password"];NEHotspotHelperResponse*response=[cmd createResponse:kNEHotspotHelperResultSuccess];NSLog(@"Response CMD %@",response);[response setNetworkList:@[network]];[response setNetwork:network];[response deliver];}}}}];NSLog(@"result :%d",returnType);NSArray*array=[NEHotspotHelper supportedNetworkInterfaces];NSLog(@"wifiArray:%@",array);NEHotspotNetwork*connectedNetwork=[array lastObject];NSLog(@"supported Network Interface: %@",connectedNetwork);}

总结:

经过一番折腾发现,想要在iOS上实现系统级别的操作几乎是不可能,iOS的很多操作都是仅限于沙盒级别的操作,如果非想要一些特殊的功能,那只能去探索越狱了。

参考文献

iOS 获取系统wifi列表,wifi信号强度,并给wifi设置密码,标签(副标题)

iOS之Wifi开发探究

iOS 无法获取 WiFi 列表?一定是因为你不知道这个框架

无线路由器WPA-PSK/WPA2-PSK、WPA/WPA2、WEP加密有什么区别

无线加密的多种方法及其区别(WEP WPA TKIP EAP)

IOS NEHotspotConfigurationManager使用

苹果开发文档之joinonce属性

苹果开发文档之NetworkExtension

苹果开发文档之nehotspothelper

作者:远方的枫叶

链接:https://www.jianshu.com/p/ecf07c62525b

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

作者:远方的枫叶

链接:https://www.jianshu.com/p/ecf07c62525b

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关文章

  • 更改手机WIFI

    前言 最近有一个需求,为了方便用户操作,优化用户体验,我们需要实现在APP内控制WiFi的开关、连上指定的WiFi...

  • 更改wifiMac

    更改方法: 越狱手机在飞行模式下 2.手机和电脑在同一wifi下 3.在终端下输入ssh root@xxx.xxx...

  • ARR mobile phone网控

    1·打开机器WiFi,手机连接,WiFi密码如图获取“WIFI Host password” 2·进入WiFi,“...

  • WIFI走丢了怎么办?

    没有WIFI了,要什么电脑手机?电脑连不上WIFI了,手机跟WIFI失联了,来,简单几步看看WIFI是在那里走丢的...

  • 学习socket笔记

    获取手机wifi 名称 和mac地址 获取手机在链接wifi网络下 ip地址

  • 电脑突然无法上网

    电脑突然无法上网,关闭WIFI再开启,依然无法上网,显示为无法找到wifi网络。解决办法:打开网络共享中心-更改适...

  • android app 弱网测试

    模拟手机/设备WIFI的弱网测试,步骤如下: 新建wifi热点,手机等设备,连接wifi热点 这里介绍做法,电脑上...

  • Android Studio插件

    Android Studio插件 1.通过WiFi调试手机:Android Wifi ADB、ADB WiFI 2...

  • 持续收集Android Studio好用的插件~~只选对的!

    1.通过WiFi调试手机:Android Wifi ADB、ADB WiFI 2.ButterKnife 注解生成...

  • android studio 插件

    1.通过WiFi调试手机: Android Wifi ADB、ADB WiFI 2.ButterKnife 注解生...

网友评论

      本文标题:更改手机WIFI

      本文链接:https://www.haomeiwen.com/subject/kkvgwctx.html