前戏
苹果ios 14针对本地局域做了一些权限限制,详情见链接:
wwdc翻译过来凑字数的
什么是本地网络?
这里的本地网络其实就是我们常说的局域网,是将设备接入路由器以后形成的网络,设备可以通过这张网络互相通信,如我们的设备发现、设备绑定、局域网优先等功能都是使用的本地网络。
从 ios 13 开始,应用想要获得当前连接到的 wi-fi 名称,那就必须要获得定位权限。因为通过识别 wi-fi 名称, 应用就能轻松地在你和周围的人之间建立大数据网络。但是不给定位权限不代表应用就没有办法跟踪你了,因为应用可以通过本地网络里的设备进行跟踪。
为什么需要向用户申请权限?
和ios 13获取wifi名称需要通过定位权限类似,苹果加强了对用户隐私安全权限,这里也是类似的问题。在过去的 ios 版本中,应用可以随意扫描本地网络中的设备,因此应用就可以很轻松地得到本地网络里所有设备的名称和 地址。mac 地址是一种确认网络设备位置的地址,每个网卡都有一个唯一的 mac 地址,加上 mac 地址也具有唯一性,设备厂商会按照一定的规律分配 mac,所以不同的局域网都是独一无二可以识别的。比方说,你从线下渠道买了个新相机,拍完照片利用相机自带的 wi-fi 将照片导入到手机上。这时候带有某个推广模块的应用对局域网发起了一次扫描,识别到了一个新的设备,推广模块会将相机的 mac 地址上传了云端,进行简单的识别对比以后,很容易知道这个 mac 地址属于相机。这样带有推广模块的应用都会在画像里给你加上「相机用户」这样的标签,当你下次打开带有同一个推广模块的购物应用时,你就会看到推荐了一堆和相机有关的东西。
那些应用需要使用本地网络?
- 利用本地网络进行设备发现
- 利用本地网络进行数据传输
- 网络调试工具
影响范围
主要影响无法使用socket或者bonjour做一些局域网的发现,数据传输。
对局域网应用如:智能家居类,局域网游戏,网络测试工具等等。本人测试了下其实也没有那么大,因为发现这个开关,app下次启动后可能不会生效,暂时未定位原因。
怎么解决?
相信很多人都很奇怪为什么不整个权限申请或状态查询的接口,在翻了一些资料后发现,居然真的没有。 链接:
很无奈!
大部分应用使用局域一般使用socket或者bonjour做一些局域的发现,数据传输。说在调用的时候会出现code:65 desc:no route to host。这是其实就是所谓的无本地网络权限。但是我在测试时发现有时候即使是关掉本地网络权限的开关,也能正常的使用udp、tcp。简直不敢信!难道ios 14也会想ios 13一开始出来一样各种坑满天飞?
这里的思路是
- 通过接口获取本机的ip地址
- 使用()来ping手机的ip
整个流程的大概耗时在0.13-0.2秒之间,大部分在0.17秒左右。可能耗时还能接受。但是不知道某些路由器是否可以设置禁止ping。如果有那就炸裂了。 下面上简单的代码
- (void)viewdidload { [super viewdidload]; // do any additional setup after loading the view. nsdictionary *router = [ldsrouterinfo getrouterinfo]; pinger = [[simpleping alloc] initwithhostname:router[@"ip"]]; pinger.delegate = self; [self->pinger start]; } - (void)simpleping:(simpleping *)pinger didstartwithaddress:(nsdata *)address { if (timer) { return; } timer = dispatch_source_create(dispatch_source_type_timer, 0, 0, dispatch_get_main_queue()); dispatch_source_set_timer(timer, dispatch_time_now, 2 * nsec_per_sec, 0 * nsec_per_sec); dispatch_source_set_event_handler(timer, ^{ [pinger sendpingwithdata:nil]; }); dispatch_resume(timer); } - (void)simpleping:(simpleping *)pinger didsendpacket:(nsdata *)packet sequencenumber:(uint16_t)sequencenumber { nslog(@"可以使用局域网"); } - (void)simpleping:(simpleping *)pinger didfailtosendpacket:(nsdata *)packet sequencenumber:(uint16_t)sequencenumber error:(nserror *)error { if (error.code == 65) {//no route to host nslog(@"不可以使用局域网"); } }
友情提示
- 调上面接口可以触发首次启动本地网络权限的系统弹窗
- 不知道某些路由器是否可以设置禁止ping
- 整理流程在iphone 6sp耗时130-200毫秒之间。平均值在160毫秒左右
- 上面代码未正式上线,本人也在测试中,请酌情使用。