iOS客户端公共WIFI解决方案探究

众所周知,iOS系统WIFI相应的API极少,而且大部分API为私有接口,一不小心审核就可能被拒。iOS9之前公共WIFI的解决方案已不适用。在iOS9发布之后,苹果推出了NetworkExtension,其中的NEHotspotHelper可以获取WIFI列表。同样我们也可以根据用户所在的位置,服务器返回用户附近的WIFI列表。

方案一 :使用NEHotspotHelper获取WIFI列表。

在使用NEHotspotHelper相应API的时候需要申请“Network Extension Framework”使用权限,大概需要三周左右。

相应API可以参考Developer Documentation,如下所示。

NEHotspotNetwork

代码实现扫描周围无线网络如下,但在本人测试的过程中因为没申请“Network Extension Framework”使用权限的原因,此方法并没返回相应数据,所以并没有获取到设备的WIFI列表(尴尬ing~~)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#pragma mark --- 扫描周围的无线网络 ---
- (BOOL)scanWifiInfo{

NSMutableDictionary* options = [[NSMutableDictionary alloc] init];
[options setObject:@"NEHotspotHelper" forKey: kNEHotspotHelperOptionDisplayName];
dispatch_queue_t queue = dispatch_queue_create("EFNEHotspotHelperDemo", NULL);

BOOL returnType = [NEHotspotHelper registerWithOptions: options queue: queue handler: ^(NEHotspotHelperCommand * cmd) {

NEHotspotNetwork* network;
if (cmd.commandType == kNEHotspotHelperCommandTypeEvaluate || cmd.commandType == kNEHotspotHelperCommandTypeFilterScanList) {
// 遍历 WiFi 列表,打印基本信息
for (network in cmd.networkList) {
NSString* wifiInfoString = [[NSString alloc] initWithFormat: @"SSID: %@\nMac地址: %@\n信号强度: %f\nCommandType:%ld\n\n",
network.SSID, network.BSSID, network.signalStrength, (long)cmd.commandType];
NSLog(@"------ %@ ------",wifiInfoString);

// 检测到指定 WiFi 可设定密码直接连接
if ([network.SSID isEqualToString: @"测试 WiFi"]) {
[network setConfidence: kNEHotspotHelperConfidenceHigh];
[network setPassword: @"测试 WiFi 密码"];
NEHotspotHelperResponse *response = [cmd createResponse: kNEHotspotHelperResultSuccess];
NSLog(@"Response CMD: %@", response);
[response setNetworkList: @[network]];
[response setNetwork: network];
[response deliver];
}
}
}

}];

return returnType;

}
使用NEHotspotHelper注意事项:
1
2
3
4
<key>UIBackgroundModes</key>
<array>
<string>network-authentication</string>
</array>
  • 需要将工程中Capabilities的Background Modes开启。
  • 需要将工程中Capabilities的Wireless Accessory Configuration开启。
  • 需要在.entitlements中添加HotspotHelper权限代码。
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.networking.HotspotHelper</key>
<true/>
<key>com.apple.external-accessory.wireless-configuration</key>
<true/>
</dict>
</plist>

此方法的缺点:

  • 只支持iOS 9 + 的设备,系统为iOS 9 以下的设备不支持。
  • 调用NEHotspotHelper的API需要申请,申请通过后方可使用,否则调用无返回信息。
  • 有时候会获取不到WIFI列表,需要用户到手机的 设置 ->无线局域网 中开关一次WIFI,进行刷新(特么……)。
  • 不安全,iOS 10.3.1之前的设备可能存在高危漏洞,还有WPA2系列漏洞

代码地址:NEHotspotNetwork

方案二:根据用户所在位置,服务器返回相应WIFI列表。

通过上传用户所在地的经纬度,服务端返回用户所在地所有可用的WIFI列表和WIFI密码,然后用户在手机的设置中自己输入相应WIFI密码。

具体流程:

  1. 客户端获取用户的经纬度上传服务器
  2. 服务器返回用户周围的所有WIFI名称和密码。
  3. 用户在客户端复制WIFI密码。
  4. 到手机的设置 ->无线局域网 中找到相应WIFI 然后粘贴密码。

缺点:

  • 需要用户自己到设置中进行操作。

参考资料