一: 介绍
近几年,智能设备越来越火,这些智能设备中,有很大一部分是通过手机来控制硬件设备,来达到预期的效果,这中间少不了要使用到蓝牙功能,通过蓝牙来通信来控制设备。
除了蓝牙控制设备之外,还可以通过Wi-Fi来控制设备,iOS11前只能跳转到系统设置界面手动连接Wi-Fi,iOS11之后苹果提供 NEHotspotConfiguration ,NEHotspotConfigurationManager 类直连周边Wi-Fi。
这篇文章主要和大家分享iOS11之后在App内自动连接Wi-Fi,Wi-Fi信息获取,Wi-Fi检测等功能。
二:权限配置
苹果提供的 NEHotspotConfiguration ,NEHotspotConfigurationManager需要在开发者账号和项目中做如下配置。
1. 打开App IDs Hotspot 权限
登陆https://developer.apple.com,如果App ID已经存在,只需增加Hotspot 权限,如果App ID不存在,新建一个并添加Hotspot 权限。
配置的App ID需要与项目中的Bundle ID一致。
2. 添加依赖库NetworkExtension.framework
在项目中Build Phases - Link Binary With Libraries中添加 依赖库NetworkExtension.framework
3. 打开Capabilities里的Hotspot Configuration
Xcode - Capabilities - Hostpot Configuration 开关打开
三:NEHotspotConfiguration库分析
在NEHotspotConfiguration库中有3个属性,分别是:
- SSID:要连的wifi名称
- joinOnce:默认是NO,会保留配置过的wifi,YES即是不保存
- lifeTimeInDays: 配置的生命周期
源码如下:
/*!
* @property SSID
* @discussion SSID of the Wi-Fi Network.
*/
@property (readonly) NSString * SSID API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);
/*!
* @property joinOnce
* @discussion if set to YES the configuration will not be persisted. Default is NO.
*/
@property BOOL joinOnce API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);
/*!
* @property lifeTimeInDays
* @discussion The lifetime of the configuration in days. The configuration is stored for the
* number of days specified by this property. The minimum value is 1 day and maximum value is 365 days.
* A configuration does not get deleted automatically if this property is not set or set to an invalid value.
* This property does not apply to Enterprise and HS2.0 networks.
*/
@property (copy) NSNumber * lifeTimeInDays API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);
有4个实例化方法,分别是:
- 无密码的开放网络
- 受保护的WEP或WPA / WPA2个人Wi-Fi网络创建由SSID标识的新热点配置
- 具有EAP设置的WPA / WPA2企业Wi-Fi网络
- 具有HS 2.0和EAP设置的Hotspot 2.0 Wi-Fi网络
源码如下:
/*!
* @method initWithSSID:
* @discussion
* A designated initializer to instantiate a new NEHotspotConfiguration object.
* This initializer is used to configure open Wi-Fi Networks.
*
* @param SSID The SSID of the Open Wi-Fi Network.
* Length of SSID must be between 1 and 32 characters.
*/
- (instancetype)initWithSSID:(NSString *)SSID API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);
/*!
* @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 *)SSID
passphrase:(NSString *)passphrase isWEP:(BOOL)isWEP API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);
/*!
* @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 *)SSID
eapSettings:(NEHotspotEAPSettings *)eapSettings API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);
/*!
* @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 *)eapSettings API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);
四:NEHotspotConfigurationManager库分析
在NEHotspotConfigurationManager库中提供了四个方法,分别是:
- 应用你的Configuration,会弹出系统框询问是否加入
- 通过ssid删除一个配置
- 删除Hotspot 2.0域名标识的Wi-Fi热点配置
- 获取配置过的wifi名称。如果你设置joinOnce为YES,这里就不会有了
源码如下:
/*!
* @method applyConfiguration:
* @discussion This function adds or updates a Wi-Fi network configuration.
* @param configuration NEHotspotConfiguration object containing the Wi-Fi network configuration.
* @param completionHandler A block that will be called when add/update operation is completed.
* This could be nil if application does not intend to receive the result.
* The NSError passed to this block will be nil if the configuration is successfully stored, non-nil otherwise.
* If the configuration is found invalid or API encounters some other error then completionHandler is called
* with instance of NSError containing appropriate error code. This API attempts to join the Wi-Fi network
* if the configuration is successfully added or updated and the network is found nearby.
*
*/
- (void)applyConfiguration:(NEHotspotConfiguration *)configuration
completionHandler:(void (^ __nullable)(NSError * __nullable error))completionHandler API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);
/*!
* @method removeConfigurationForSSID:
* @discussion This function removes Wi-Fi configuration.
* If the joinOnce property was set to YES, invoking this method will disassociate from the Wi-Fi network
* after the configuration is removed.
* @param SSID Wi-Fi SSID for which the configuration is to be deleted.
*/
- (void)removeConfigurationForSSID:(NSString *)SSID API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);
/*!
* @method removeConfigurationForNetworkName:
* @discussion This function removes Wi-Fi configuration.
* @param domainName HS2.0 domainName for which the configuration is to be deleted.
*/
- (void)removeConfigurationForHS20DomainName:(NSString *)domainName API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);
/*!
* @method getConfiguredSSIDsWithCompletionHandler:
* @discussion This function returns array of SSIDs and HS2.0 Domain Names that the calling application has configured.
* It returns nil if there are no networks configurred by the calling application.
*/
- (void)getConfiguredSSIDsWithCompletionHandler:(void (^)(NSArray<NSString *> *))completionHandler API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);
到这里配置及源码分析的前期工作已经做完。
五:加入Wi-Fi实现解析
首先引入 NetworkExtension 库
#import <NetworkExtension/NetworkExtension.h>
然后需要调用NEHotspotConfiguration库方法,根据不同的情况,选择使用不同的方法,这里使用受保护的WEP或WPA举例
NEHotspotConfiguration *hotspotConfig = [[NEHotspotConfiguration alloc]initWithSSID:_wifiName.text passphrase:_wifiPassword.text isWEP:NO];
然后开始连接 ,调用applyConfiguration此方法后系统会自动弹窗确认,根据返回的error.code来判断Wi-Fi是否加入成功,error code = 7 为用户点击了弹框取消按钮,error code = 13 为已连接
[[NEHotspotConfigurationManager sharedManager] applyConfiguration:hotspotConfig completionHandler:^(NSError * _Nullable error) {
if (error && error.code != 13 && error.code != 7) {
NSLog(@"加入失败");
}else if(error.code ==7){
NSLog(@"已取消");
}else{
NSLog(@"已连接");
}
}];
五:Wi-Fi列表实现解析
在Android中设备周围的Wi-Fi信息是可以扫面获取到的,iOS设备至今也没有完全开放相关接口,如果真有该需求
,需要填写申请表申请,通过后方可使用,咱们这里分享的Wi-Fi列表,是NEHotspotConfigurationManager库中的getConfiguredSSIDsWithCompletionHandler方法,可以获取到已经保存过的Wi-Fi信息,实现源码如下:
[[NEHotspotConfigurationManager sharedManager] getConfiguredSSIDsWithCompletionHandler:^(NSArray<NSString *> * array) {
for (NSString * str in array) {
self.WiFiListTextView.text = [NSString stringWithFormat:@"%@\n%@",self.WiFiListTextView.text,str];
NSLog(@"加入过的WiFi:%@",str);
}
}];
六:Wi-Fi测速实现解析
通过Wi-Fi测速可以获取到Wi-Fi强度、上行速度、下行速度,我在demo中封装了SpeedController类来实现该功能,通过下面两个方法来实现:
//获取信号强度(0到1)
+(void)getSignalStrength:(void(^)(float signalStrength))resultBlock;
//获取下行速度,上行速度(单位是 MB/S)
-(void)getDownstreamSpeedAndUpstreamSpeed:(void(^)(float downstreamSpeed,float upstreamSpeed))resultBlock;
源码Demo获取方法
关注 【网罗开发】微信公众号,回复【93】便可领取。
网罗天下方法,方便你我开发,更多iOS技术干货等待领取,所有文档会持续更新,欢迎关注一起成长!