
iOS开发避免不开系统权限的问题,如何在APP中以更加友好的方式向用户展示系统权限,似乎也是开发过程中指的深思的一件事。
那如何提高用户获取权限的通过率呢?以下几种方式或许是不错的尝试:
上面的只是一些尝试,与本文的主要讲述内容关系不大,接下来我们主要来看一下常用的一些系统权限的状态获取以及主动唤起权限请求的方法。
相机权限
相册权限
日历权限
麦克风权限
推送权限
定位权限
提醒事项权限
通讯录权限
互联网权限
蓝牙权限
引入头文件 #import <AVFoundation/AVFoundationh>
引入头文件 #import <Photos/Photosh>
引入头文件 #import <EventKit/EventKith>
引入头文件 #import <AVFoundation/AVFoundationh>
引入头文件 #import <UserNotifications/UserNotificationsh>
引入头文件 #import <CoreLocation/CoreLocationh>
封装方法调用
TenLocationManagerh
TenLocationManagerm
引入头文件 #import <EventKit/EventKith>
引入头文件
iOS 90前 #import <AddressBook/AddressBookh>
iOS 90后 #import <Contacts/Contactsh>
引入头文件 #import <CoreTelephony/CTCellularDatah>
系统未提供接口供开发者手动请求网络权限,iOS10以上系统,应用首次请求网络会自动d出,一个应用只d出一次,卸载也不会重新d出
引入头文件 #import <CoreBluetooth/CoreBluetoothh>
TenBluetoothManagerh
TenBluetoothManagerm
iOS14新增加本地网络权限 Privacy - Local Network Usage Description
如有本地网络使用场景需要在 infoplist 中增加 Bonjour services 字段(如投屏加入 _leboremote_tcp )
查看使用本地网络的三方库方法:在项目目录下使用 grep -r SimplePing 命令即可
Apple官方无具体API查询Local Network权限,这里采用建立定时器对本地网络请求,如果请求不通则无Local Network权限。需要使用Ping库( https://githubcom/yluo8090/Common/tree/main/Ping )具体见下:
方案1:使用group和semaphore
方案2:group_enter和group_leave也可以实现
方案1实现例子
方案2实现例子
IP直连可以避免localDNS解析导致的DNS劫持,但是在iOS中不仅仅是将host直接换成IP地址就可以了,还有以下需要注意的问题。
发送HTTPS请求首先要进行SSL/TLS握手,握手过程大致如下:
上述过程中,和HTTPDNS有关的是第3步,客户端需要验证服务端下发的证书,验证过程有以下两个要点:
如果上述两点都校验通过,就证明当前的服务端是可信任的,否则就是不可信任,应当中断当前连接。 当客户端使用HTTPDNS解析域名时,请求URL中的host会被替换成HTTPDNS解析出来的IP,所以在证书验证的第2步,会出现domain不匹配的情况,导致SSL/TLS握手不成功 。
针对 domain不匹配 问题,可以采用如下方案解决:hook证书校验过程中第2步,将IP直接替换成原来的域名,再执行证书验证。
方法为在客户端收到服务器的质询请求代理方法 -URLSession:task:didReceiveChallenge:completionHandler: 中,首先从header中获取host(第一点注意事项:HTTP请求头HOST字段设置),从header中如果没有取到host,就去URL中获取host(降级为LocalDNS解析时不进行替换),然后拿着host在自己的方法-evaluateServerTrust:forDomain:中创建SSL Policy证书校验策略,然后对证书进行校验。
SNI(Server Name Indication)是为了解决一个服务器使用多个域名和证书的SSL/TLS扩展。它的工作原理如下:
在连接到服务器建立SSL链接之前先发送要访问站点的域名(Hostname),服务器根据这个域名返回一个合适的证书。
目前,大多数 *** 作系统和浏览器都已经很好地支持SNI扩展,OpenSSL 098也已经内置这一功能。
上述过程中,当客户端使用HTTPDNS解析域名时,请求URL中的host会被替换成HttpDNS解析出来的IP,导致SSL/TLS握手中服务器接收到的客户端发出的clientHello中的SNI为host解析后的IP,从而无法找到匹配的证书,只能返回默认的证书或者不返回,所以会出现SSL/TLS握手不成功的错误。
比如当你需要通过HTTPS访问CDN资源时,CDN的站点往往服务了很多的域名,所以需要通过SNI指定具体的域名证书进行通信。
SNI(单IP多HTTPS证书)场景下,iOS上层网络库 NSURLConnection/NSURLSession 没有提供接口进行 SNI 字段 配置,因此需要 Socket 层级的底层网络库例如 CFNetwork,来实现 IP 直连网络请求适配方案。苹果提供的一些指导,在 Networking Programming Topics 中,可以通过如下方式指定一个TLS hostname:
我们使用CFNetwork进行HTTP网络请求的方法,详见 [2] 。
Apple - Communicating with HTTP Servers
Apple - HTTPS Server Trust Evaluation - Server Name Failures
Apple - HTTPS Server Trust Evaluation - Trusting One Specific Certificate
[1]:HTTPS场景IP直连方案说明
[2]:使用CFNetwork进行HTTP请求
1、避免系统使用蜂窝数据流量,就是不要开启蜂窝移动数据,或者是在使用的时候避免使用蜂窝移动数据去更新或者是下载系统服务,后者是可以直接通过设置来避免。
2、打开系统设置,找到itunes Store和AppStore,进入到里面之后,把最下面的使用蜂窝移动数据都关闭,这样系统就不会在使用蜂窝移动数据的使用自动下载更新程序。
一个unwind segue可以在推送,模型和d出连线(如果你d出导航条的导航项,关闭d出项或者销毁现有视图控制器的模型)时使用该技术。在它顶层,你可以直接展开多个而不仅仅是一个推送/模型/d出项等。你可以使用一个解绑 *** 作实现原本需要多步才
首先创建并行队列,创建队列组,将队列和需要处理的网络请求分别添加到组中,当组中所有队列处理完事件后调用dispatch_group_notify,我们需要在里边处理事件。由于队列在处理网络请求时将”发送完一个请求”作为事件完成的标记(此时还未获得网络请求返回数据),所以在这里需要用信号量进行控制,在执行dispatch_group_notify前发起信号等待(三次信号等待,分别对应每个队列的信号通知),在每个队列获取到网络请求返回数据时发出信号通知。这样就能完成需求中的要求。
如果需求中改为:同时存在A,B,C三个任务,要求ABC依次进行处理,当上一个完成时再进行下一个任务,当三个任务都完成时再处理事件。这时只需要将队列改为串行队列即可(不在需要信号量控制)。
假如for遍历发送HTTP并发请求时,由于服务端响应数据的时间不同,会造成请求到的数据集合与发请求的顺序非一一对应,思路如下,创建可变字典 NSMutableDictionary 建立起请求与数据集合的对应关系。然后遍历字典,按 key 的顺序重新整理数据集合
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)