iOS WIFI
一、公共WIFI综述
现在很多公司都在做免费WIFI,车站、公交、地铁、餐厅,只要是人员密集流动的地方就有WIFI,免费WIFI从最初的网页认证方式也逐渐向客户端认证方式偏移。本文主要讨论iOS认证上网的解决方案。
iOS端WIFI应用的相关开发,主要存在以下问题:
iOS系统WIFI相关的接口很少,大部分接口都是私有接口
在设备连接上WIFI,没有通过路由器认证前,如果关闭iOS自动弹出的Portal页面,iPhone的WIFI会自动断开
如何禁止iOS系统自动弹Portal页面
公共WIFI的名称确定及不确定时的处理办法
本文主要讨论在使用公开的API,即可以提交到App Store的应用。
二、基础信息获取
1. 获取网卡IP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
+ (NSString *)localIPAddress { NSString *localIP = nil; struct ifaddrs *addrs; if (getifaddrs(&addrs)==0) { const struct ifaddrs *cursor = addrs; while (cursor != NULL) { if (cursor->ifa_addr->sa_family == AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0) { NSString *name = [NSString stringWithUTF8String:cursor->ifa_name]; if ([name isEqualToString:@ "en0" ]) // Wi-Fi adapter { localIP = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)cursor->ifa_addr)->sin_addr)]; break ; } } cursor = cursor->ifa_next; } freeifaddrs(addrs); } return localIP; } |
2. 获取网卡信息
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
|
- (NSDictionary *)getWIFIDic { CFArrayRef myArray = CNCopySupportedInterfaces(); if (myArray != nil) { CFDictionaryRef myDict = CNCopyCurrentNetworkInfo(CFArrayGetValueAtIndex(myArray, 0)); if (myDict != nil) { NSDictionary *dic = (NSDictionary*)CFBridgingRelease(myDict); return dic; } } return nil; } - (NSString *)getBSSID { NSDictionary *dic = [self getWIFIDic]; if (dic == nil) { return nil; } return dic[@ "BSSID" ]; } - (NSString *)getSSID { NSDictionary *dic = [self getWIFIDic]; if (dic == nil) { return nil; } return dic[@ "SSID" ]; } |
**注意事项**
在实际测试时,获取网卡信息**getWIFIDic**方法,在部分路由器上耗时很长(10秒以上),如果直接放在主线程中,会导致界面卡死。在认证相关的应用中,会根据网卡上的BSSID(例如:以特定3d:e6:c3开头的即为本公司架设网络)来判断是否属于本公司的路由。SSID、BSSID若为应用启动时必须获取的信息(我们公司的应用,就是这种),这个时候怎样处理呢?
放在异步线程,获取到网卡信息再初使化界面,这种方法依然会导致在某些路由器下初次打开界面超长时间的等待,我们的处理方法是,如果3秒内能够获取到相应的配置信息,直接根据配置信息初使化界面,在超过3秒时,给予默认的假WIFI信息,初使化界面。异步线程获取到真实的配置信息后,再重新更新界面。
三、认证过程中的棘手问题
1. Portal禁止弹出与WIFI自动关闭的问题
正常情况,用户使用iPhone手机连接带有Portal认证的路由器,在连接成功后,iOS系统会在已有列表中随机选择连接指定的网址(例如:www.itools.info)以测试当前路由器是否需要Portal认证。在需要Portal认证的网络,系统会弹出Portal页面,这个时候,如果用关掉portal页面,或者直接切换到其它应用,WIFI网络会直接自动断开(根本不给客户端认证机会^_^)。
我们的解决办法是路由器白名单,让路由器放行所有Portal测试的IP,以下为测试的域名:
1
2
3
4
5
6
|
www.appleiphonecell.com captive.apple.com www.itools.info www.ibook.info www.airport.us www.thinkdifferent.us |
对应的IP地址:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
23.207.103.91 23.33.54.18 23.44.167.91 23.67.183.91 96.7.103.91 23.42.71.91 23.34.105.211 23.59.167.91 23.42.184.50 23.47.232.190 23.77.23.91 23.194.87.91 23.61.91.190 23.218.12.50 23.2.38.95 23.46.135.91 172.225.213.179 218.205.66.94 23.64.251.249 23.58.250.189 |
将以上所有IP加到路由器的白名单中,即可解决iPhone断开WIFI的问题,但是同时也不自动弹出Portal页面了,用户打开浏览器才会重定向到Portal页面。
2. WIFI名确定解决方法
如果公司部署的公共WIFI名确定的情况,就比较简单了,不需要配置上述白名单也可以保证WIFI不断开,具体办法是,在程序启动时,向iOS系统注册SSID,方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
- (void)registerNetwork:(NSString *)ssid { NSString *values[] = {ssid}; CFArrayRef arrayRef = CFArrayCreate(kCFAllocatorDefault,(void *)values, (CFIndex)1, &kCFTypeArrayCallBacks); if ( CNSetSupportedSSIDs(arrayRef)) { NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces(); CNMarkPortalOnline((__bridge CFStringRef)(ifs[0])); NSLog(@ "%@" , ifs); } } |
四、总结
苹果对于WIFI这块公开的API非常少,在开发公共WIFI应用时会遇到各种问题,上面是在使用非私有API的一些解决方案,如果大家有更优的办法,欢迎留言分享。如果公司有企业账号可以通过调用私有API的办法来处理大部分需求。
iOS WIFI的更多相关文章
- NetworkExtension
一, 按照网上的方法: iOS 无法获取 WiFi 列表?一定是因为你不知道这个框架 提交了申请.两个小时候后苹果回应邮件.意思就是如果只是使用 App Proxy, Content Filter, ...
- iOS开发中获取WiFi相关信息
iOS 开发中难免会遇到很多与网络方面的判断,这里做个汇总,大多可能是与WiFi相关的. 1.Ping域名.Ping某IP 有 时候可能会遇到ping 某个域名或者ip通不通,再做下一步操作.这里的p ...
- IOS零碎技术整理(3)-获取wifi列表
1. 该功能实现基于MobileApple80211框架来进行开发,而目前该框架成为了私有框架,其中的API均为私有API. 如果使用这些API可能导致应用不能上app store或者ios版本升 ...
- iOS开发之APP推送设置WIFI
在iOS开发过程中,有时需要连接网络.当访问请求,检测到网络不可用时,需要提示用户手动进行设置网络并告知用户操作路径设置可用的网络. 只需一行代码即可实现: - (void)viewDidLoad { ...
- 微信连WiFi关注公众号流程更新 解决ios微信扫描二维码不关注就能上网的问题
前几天鼓捣了一下微信连WiFi功能,设置还蛮简单的,但ytkah发现如果是ios版微信扫描微信连WiFi生成的二维码不用关注公众号就可以直接上网了,而安卓版需要关注公众号才能上网,这样就少了很多ios ...
- 获取iOS设备信息(内存/电量/容量/型号/IP地址/当前WIFI名称)
1.获取电池电量(一般用百分数表示,大家自行处理就好) 1 2 3 4 -(CGFloat)getBatteryQuantity { return [[UIDevice current ...
- iOS设备中WiFi、蓝牙和飞行模式的开启与关闭
转自:http://www.cnblogs.com/OtionSky/archive/2011/11/08/iOS_WiFi_Controller.html 今天写了一段有关在iPhone程序中开关W ...
- iOS 中如何判断当前是2G/3G/4G/5G/WiFi
5G 什么的,还得等苹果API更新啊,不过将来还是这个处理过程就是了. 关于判断当前的网络环境是2G/3G/4G,这个问题以前经常看到,最近在一工程里看到了如果判断的API.而在撸WebRTC音视频通 ...
- 在 iOS 上通过 802.11k、802.11r 和 802.11v 实现 Wi-Fi 网络漫游
原文: https://support.apple.com/zh-cn/HT202628 了解 iOS 如何使用 Wi-Fi 网络标准提升客户端漫游性能. iOS 支持在企业级 Wi-Fi 网络上 ...
随机推荐
- 学习了ZKW费用流
所谓ZKW费用流,其实就是Dinic. 若干年前有一个人发明了最小增广路算法,每次用BFS找一条增广路,时间O(nm^2) 然后被DinicD飞了:我们为什么不可以在长度不变时多路增广呢?时间O(n^ ...
- SparkContext.setCheckpointDir()
class SparkContext extends Logging with ExecutorAllocationClient Main entry point for Spark function ...
- Eclipse中部署hadoop2.3.0
1 eclipse中hadoop环境部署概览 eclipse 中部署hadoop包括两大部分:hdfs环境部署和mapreduce任务执行环境部署.一般hdfs环境部署比较简单,部署后就 可以在ecl ...
- nova help network-create
chen@controller:~$ nova help network-create usage: nova network-create [--fixed-range-v4 <x.x.x.x ...
- 【iHMI43 4.3寸液晶模块】demo例程(版本1.03)发布
============================== 技术论坛:http://www.eeschool.org 博客地址:http://xiaomagee.cnblogs.com 官方网店:h ...
- GIT: 远程建立一个仓库,然后复制到本地
1. 登录 GIT,创建一个新的仓库 gitskills 2. 创建的时候,要选择 Initialize this repository with a readme ,让GitHub初始化仓库 3. ...
- HDU 4738 Caocao's Bridges(Tarjan求桥+重边判断)
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- Frenetic Python实验(三)
实验5 repeater 这个实验在HelloSDNWorld里面做的实验是一样的.HelloSDNWorld 目的:模拟一个有多个端口的中继器. This application implement ...
- PHP+jQuery 注册模块的改进之三:使用 Smarty3
Smarty3.1X( 最新版本 3.1.19) 比起Smarty2.x修改了不少特性.我把这个模块使用Smarty3.1.18 ( 下载地址http://www.smarty.net/files/S ...
- python 执行文件时传参
## test.py ## ####################### import sys if __name__ == "__main__": args = sys.arg ...