《 iOS9 适配教程》总共六篇,限于篇幅这里只写一篇了。 更多请戳--》原文地址: 《 Github 链接》 , 1. Demo1_iOS9 网络适配_ATS :改用更安全的 HTTPS[摘要]为了强制增强数据访问安全, iOS9 默认会把 <del>所有的 http 请求</del> 所有从 官方文档 App Transport Security Technote 对 ATS 的介绍: 注:有童鞋反映:服务器已支持 TLS 1.2 SSL ,但 iOS9 上还是不行,还要进行本文提出的适配操作。 那是因为:要注意 App Transport Security 要求 TLS 1.2 ,而且它要求站点使用支持 forward secrecy 协议的密码。证书也要求是符合 ATS 规格的, ATS 只信任知名 CA 颁发的证书,小公司所使用的 self signed certificate ,还是会被 ATS 拦截。。因此慎重检查与你的应用交互的服务器是不是符合 ATS 的要求非常重要。对此,建议使用下文中给出的 NSExceptionDomains ,并将你们公司的域名挂在下面。下文也会详细描述该问题。 官方文档 App Transport Security Technote 对 CA 颁发的证书要求:
在讨论之前,跟往常一样,先说下 iOS 程序猿们最关心的问题: 跟我有毛关系?需要我加班吗?!首先咱们来看下业内对 Apple 这一做法的评论: 这是某社交 App 上讨论,看来业内还是吐槽声和肯定声同在。 结论是:
书归正传 [严肃脸] ,我们正式讨论下 WHAT , WHY , HOW :
WHAT (什么是 SSL/TLS ?跟 HTTP 和 HTTPS 有什么关系)什么是 SSL/TLS ? TLS 是 SSL 新的别称: “ TLS1.0 ”之于“ SSL3.1 ”,犹“公元 2015 ”之于“民国 104 ”,“一千克”之于“一公斤”:称呼不同,意思相同。 SSL 3.0 版本之后的迭代版本被重新命名为 TLS 1.0 :TLS 1.0 = SSL 3.1。所以我们平常也经常见到 “ SSL/TLS ” 这种说法。 目前,应用最广泛的是 TLS 1.0 ,接下来是 SSL 3.0 。目前主流浏览器都已经实现了 TLS 1.2 的支持。 常用的有下面这些:
那为什么标题是“使用 HTTPS ”而没有提及 SSL 和 TLS 什么事? 要理解这个,要看下他们之间的关系:
或者
也就是说:
WHY (以前的 HTTP 不是也能用吗?为什么要用 SSL/TLS ? Apple 是不是又在反人类?)
不使用 SSL/TLS 的 HTTP 通信,所有信息明文传播,带来了三大风险:
SSL/TLS 协议是为了解决这三大风险而设计的,希望达到: SSL/TLS 的作用,打个比方来讲: 如果原来的 HTTP 是塑料水管,容易被戳破;那么如今新设计的 HTTPS 就像是在原有的塑料水管之外,再包一层金属水管( SSL/TLS 协议)。一来,原有的塑料水管照样运行;二来,用金属加固了之后,不容易被戳破。 HOW (如何适配?---弱弱地问下:加班要多久?)正如文章开头所说:
总之:
方案一:立即让公司的服务端升级使用 TLS 1.2 ,以解析相关数据。 方案二:虽 Apple 不建议,但可通过在 Info.plist 中声明,倒退回不安全的网络请求依然能让 App 访问指定 http ,甚至任意的 http ,具体做法见 gif 图,示例 Demo 见 Demo1 这也是官方文档和 WWDC 给出的解决方案: 即使你的应用使用的是:你没有权限控制的 CDN (Content Delivery Network ),而且它不支持 HTTPS ! 也别担心, Apple 都替你考虑好了:
开发者可以针对某些确定的 URL 不使用 ATS ,这需要在工程中的 info.plist 中标记 NSExceptionDomains 。在 NSExceptionDomains 字典中,可以显式的指定一些不使用 ATS 的 URL 。这些你可以使用的例子可以是:
这些关键字使我们可以更加细致的设置针对不使用 ATS 的域名情况下禁用 ATS 或者一些特殊的 ATS 选项。 你可能注意到一些关键字像是使用了一些其他关键字中的词但是在前面加上了"ThirdParty"字样,比如列表里最后三个:
在功能上,这些关键字与不含有"ThirdParty"的关键字有同样的效果。而且实际运行中所调用的代码将会完全忽略是否使用"ThirdParty"关键字。你应该使用适用于你的场景的关键字而不必过多考虑这些。 关于 App Transport Security ,每个应用都属于 4 个大类当中的一类。我们来看看每一个大类都是怎样影响应用的。
下面分别做一下介绍: 1.HTTPS Only (只有 HTTPS ,所有情况下都使用 ATS )如果你的应用只基于支持 HTTPS 的服务器,那么你太幸运了。你的应用不需要做任何改变。 唯一需要做的事情就是使用 但也有人遇到过这样的疑惑:服务器已支持 TLS 1.2 SSL ,但 iOS9 上还是不行,还要进行本文提出的适配操作。 那是因为:要注意 App Transport Security 要求 TLS 1.2 ,而且它要求站点使用支持 forward secrecy 协议的密码。证书也要求是符合 ATS 规格的, ATS 只信任知名 CA 颁发的证书,小公司所使用的 self signed certificate ,还是会被 ATS 拦截。。因此慎重检查与你的应用交互的服务器是不是符合 ATS 的要求非常重要。对此,建议使用下文中给出的 NSExceptionDomains ,并将你们公司的域名挂在下面。 官方文档 App Transport Security Technote 对 CA 颁发的证书要求:
2.Mix & Match (混合)你的应用与一个不符合 ATS 要求的服务器工作是很有可能的, 当你遇到以下三个不符合 ATS 要求的服务器的域名时:
你可以分别设置如下:
Info.plist 配置中的 XML 源码如下所示: <key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>api.insecuredomain.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <false/> </dict> </dict> </dict> 在 plist 文件里显示如下: 我们定义的第一个“例外”( Exception )告诉 ATS 当与这个子域交互的时候撤销了必须使用 HTTPS 的要求。注意这个仅仅针对在“例外”( Exception )中声明了的子域。非常重要的一点是要理解 NSExceptionAllowsInsecureHTTPLoads 关键字并不仅仅只是与使用 HTTPS 相关。这个“例外”( Exception )指明了对于那个域名,所有的 App Transport Security 的要求都被撤销了。
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>cdn.somedomain.com</key> <dict> <key>NSThirdPartyExceptionMinimumTLSVersion</key> <string>TLSv1.1</string> </dict> </dict> </dict> 在 plist 文件里显示如下: 很可能你的应用是与一个支持 HTTPS 传输数据的服务器交互,但是并没有使用 TLS 1.2 或更高。在这种情况下,你定义一个“例外”( Exception ),它指明应该使用的最小的 TLS 的版本。这比完全撤销那个域名的 App Transport Security 要更好更安全。
Info.plist 配置中的 XML 源码如下所示: <key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>thatotherdomain.com</key> <dict> <!--适用于这个特定域名下的所有子域--> <key>NSIncludesSubdomains</key> <true/> <!--扩展可接受的密码列表:这个域名可以使用不支持 forward secrecy 协议的密码--> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <!--允许 App 进行不安全的 HTTP 请求--> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <!--在这里声明所支持的 TLS 最低版本--> <key>NSExceptionMinimumTLSVersion</key> <string>TLSv1.1</string> </dict> </dict> </dict> 在 plist 文件里显示如下:
如果你的 App 中同时用到了这三个域名,那么应该是这样: <key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>api.insecuredomain.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <false/> </dict> <key>cdn.somedomain.com</key> <dict> <key>NSThirdPartyExceptionMinimumTLSVersion</key> <string>TLSv1.1</string> </dict> <key>thatotherdomain.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionRequiresForwardSecrecy</key> <false/> </dict> </dict> </dict> 3. Opt Out (禁用 ATS )上面是比较严谨的做法,指定了能访问哪些特定的 HTTP 。当然也有暴力的做法: 你可以在 Info.plist 配置中改用下面的 XML 源码: <key>NSAppTransportSecurity</key> <dict> <!--彻底倒退回不安全的 HTTP 网络请求,能任意进行 HTTP 请求 (不建议这样做)--> <key>NSAllowsArbitraryLoads</key> <true/> </dict> 在 plist 文件里显示如下: 4. Opt Out With Exceptions (除特殊情况外,都不使用 ATS )上面已经介绍了三种情景,还有一种可能你也会遇到: 当你的应用撤消了 App Transport Security,,但同时定义了一些“例外”( Exception )。当你的应用从很多的服务器上取数据,但是也要与一个你可控的 API 交互。在这种情况下,在应用的 Info.plist 文件中指定任何加载都是被允许的,但是你也指定了一个或多个“例外”( Exception )来表明哪些是必须要求 App Transport Security 的。下面是 Info.plist 文件应该会有的内容: <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> <key>NSExceptionDomains</key> <dict> <key>api.tutsplus.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <false/> </dict> </dict> </dict> 在 plist 文件里显示如下: <p><del> [注:以上在 Info.plist 配置中的做法已经验证可行,但目前 Apple 的 prerelease 版本的官方文档并未提及 Info.plist 中配置的代码,我将密切关注官方文档,如有提及,再来更新本文 .你若发现官方文档有提及了,也可在微博 @iOS 程序犭袁通知下我。] (官方文档已经有阐述)</del></p> Certificate Transparency虽然 ATS 大多数安全特性都是默认可用的, Certificate Transparency 是必须设置的。如果你有支持 Certificate Transparency 的证书,你可以检查 NSRequiresCertificateTransparency 关键字来使用 Certificate Transparency 。再次强调,如果你的证书不支持 Certificate Transparency ,此项需要设置为不可用。 如果需要调试一些由于采用了 ATS 而产生的问题,需要设置 CFNETWORK_DIAGNOSTICS 为 1 ,这样就会打印出包含被访问的 URL 和 ATS 错误在内的 NSURLSession 错误信息。要确保处理了遇到的所有的错误消息,这样才能使 ATS 易于提高可靠性和扩展性。 Q-AQ :我用 xcode7 编译的 app ,如果不在 plist 里面加关键字说明, ios9 下不能进行网络请求,因为我们服务器并不支持 TLS 1.2 ,我要是直接下载 app store 上的,什么也没有做,也是能正常网络请求。 A :本文中所罗列的新特性,多数情况下指的是 iOS9.X-SDK 新特性, AppStore 的版本是基于 iOS8.X-SDK 或 iOS7.X-SDK ,所以并不受 iOS9 新特性约束。也就是说:Xcode7 给 iOS8 打设备包可以请求到网络, Xcode7 给 iOS9 设备打的包请求不到网络, Xcode7 和 iOS9 缺一不可,才需要网络适配 ATS 。 那么,如何确认自己项目所使用的 SDK ?在 Targets->Build Setting-->Architectures Q :服务器已支持 TLS 1.2 SSL ,但 iOS9 上还是不行,还要进行本文提出的适配操作。 A :那是因为:要注意 App Transport Security 要求 TLS 1.2 ,而且它要求站点使用支持 forward secrecy 协议的密码。证书也要求是符合 ATS 规格的, ATS 只信任知名 CA 颁发的证书,小公司所使用的 self signed certificate ,还是会被 ATS 拦截。。因此慎重检查与你的应用交互的服务器是不是符合 ATS 的要求非常重要。对此,建议使用下文中给出的 NSExceptionDomains ,并将你们公司的域名挂在下面。 官方文档 App Transport Security Technote 对 CA 颁发的证书要求:
Q :我使用的是第三方的网络框架,比如 AFNetworking 、 ASIHTTPRequest 、 CFSocket 等,这个有影响没有? A : AFNetworking 有影响,其它没影响。 ATS 是只针对 现在的 AFNetworking 的 AFHTTPRequestOperationManager 实现是使用的 但 AFNetworking 也有更新计划,移除 2.Demo2_iOS9 新特性_更灵活的后台定位[ iOS9 在定位的问题上,有一个坏消息一个好消息] 坏消息:如果不适配 iOS9 ,就不能偷偷在后台定位(不带蓝条,见图)!好消息:将允许出现这种场景:同一 App 中的多个 location manager :一些只能在前台定位,另一些可在后台定位,并可随时开启或者关闭特定 location manager 的后台定位。 如果没有请求后台定位的权限,也是可以在后台定位的,不过会带蓝条: 如何偷偷在后台定位:请求后台定位权限: // 1. 实例化定位管理器 _locationManager = [[CLLocationManager alloc] init]; // 2. 设置代理 _locationManager.delegate = self; // 3. 定位精度 [_locationManager setDesiredAccuracy:kCLLocationAccuracyBest]; // 4.请求用户权限:分为:?只在前台开启定位?在后台也可定位, //注意:建议只请求?和?中的一个,如果两个权限都需要,只请求?即可, //??这样的顺序,将导致 bug :第一次启动程序后,系统将只请求?的权限,?的权限系统不会请求,只会在下一次启动应用时请求? if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8 ) { //[_locationManager requestWhenInUseAuthorization];//?只在前台开启定位 [_locationManager requestAlwaysAuthorization];//?在后台也可定位 } // 5.iOS9 新特性:将允许出现这种场景:同一 app 中多个 location manager :一些只能在前台定位,另一些可在后台定位(并可随时禁止其后台定位)。 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9 ) { _locationManager.allowsBackgroundLocationUpdates = YES; } // 6. 更新用户位置 [_locationManager startUpdatingLocation]; 但是如果照着这种方式尝试,而没有配置 Info.plist , 100%你的程序会崩溃掉,并报错:
要将 Info.plist 配置如下: 对应的 Info.plist 的 XML 源码是: <key>NSLocationAlwaysUsageDescription</key> <string>微博 @iOS 程序犭袁 请求后台定位权限</string> <key>UIBackgroundModes</key> <array> <string>location</string> </array> 3.企业级分发iOS9 之前,企业级分发十分方便:点击 App 出现“信任按钮”, iOS9 以后,企业级分发 ipa 包将遭到与 Mac 上 dmg 安装包一样的待遇:默认不能安装,也不再出现“信任按钮” 必须让用户进行 gif 图中的设置(相关 Demo : https://github.com/ChenYilong/iOS9AdaptationTips/ ) 《 iOS9 适配教程》总共六篇,限于篇幅这里只写一篇了。 更多请戳--》原文地址: 《 Github 链接》 , |
|