iOS发送http请求

本文介绍了在ATS要求HTTPS的背景下,iOS应用如何通过CFNetwork发送HTTP请求。讲解了AFNetworking与ASIHTTPRequest的限制,并建议自封装轻量级HTTP库以应对ATS策略,同时讨论了CFNetwork框架及其组件的工作原理。
摘要由CSDN通过智能技术生成

前言

苹果公司在全球开发者大会(WWDC)的一场安全演示会上,公布了一个最后期限——2017 年 1 月 1 日——即 App Store 当中的所有应用必须在这个日期之前启用一项名为 App Transport Security 的重要安全功能。

App Transport Security,简称 ATS,是苹果在 iOS 9 当中首次推出的一项安全功能。在启用 ATS 之后,它会强制应用通过 HTTPS(而不是 HTTP)连接网络服务,这能够通过加密来保障用户数据安全。
ATS在 iOS 9 当中是默认开启的,然而,开发者仍然能够关闭 ATS,让自己的应用通过 HTTP 连接传输数据——现在的情况是,这招在年底之后就行不通了。另外,ATS 要求使用 TLS v 1.2,但那些已经经过加密的批量数据例外,比如流媒体数据。

那么问题来了,2017年开始提交审核的app该怎么办?其实无非以下几点:
* 要求你的接口方全部支持https
* 可以添加 NSAllowsArbitraryLoads 为 YES 来禁用 ATS,一般来说,可能类似浏览器类的 app 比较容易能通过,不然等着被拒
* 选择使用 NSExceptionDomains 来针对特定的域名开放 HTTP 调用。如果是第三方接口的话更容易审核通过,如果访问的是自己的服务器的话,可能这个理由无法通过

当然还有一些问题:
* 请求只发生在公司内的网络环境,或者访问的就是局域网(难道内网那么多服务也搞个https么~)
* https证书太贵了买不起(大公司应该没问题
~)
* 万一把第三方接口加入了白名单可还是被苹果拒了。。。

想了想,应该还是有解决方案的:
* 通过统一的proxy来代理所有的请求,只需proxy部署https即可

然后问题又来了:
* proxy压力好大,又多了一个维护的东西,而且万一挂了~~~(大公司有专人负责proxy不怕)

不过不管怎么样,app总还是有发送http的需求,要是能够避开ATS限制就好了~~~

AFNetworking&ASIHTTPRequest

通过查询文档和动手实践,发现ATS只限制了NSURLConnection 和 NSURLSession 等应用层的网络接口,并没有限制直接使用CFNetwork发送http请求,比如著名的网络库AFNetworking 和 ASIHTTPRequest,新版AFNetworking已经基于NSURLSession,而ASIHTTPRequest是基于CFNetwork,通过实际测试,AFNetworking会受ATS限制而ASIHTTPRequest不会,但是直接引入ASIHTTPRequest会导致包增长,而且这个库已经很久不维护了,所以就自己动手封装一个轻量的http库吧,部分逻辑参照ASI做了精简优化,请看以下CFNetwork介绍和http请求示例代码

CFNetwork 简介

CFNetwork是一个高性能的低级框架,可以控制一些更底层的东西,如各种常用网络协议、socket通讯等,实际上除了socket是传输层之外,本质上还是应用层上的封装的通用API。使用者可以不用关心底层协议的实际细节。
screenshot.png
(图片来源于官方文档)

目前iOS的网络编程分四层:

  • WebKit:属于Cocoa层,苹果很多地方用到的页面渲染引擎;
  • NSURL:也属于Cocoa层,对各类URL请求的封装;
  • CFNetwork:属于Core Foundation层,基于C的封装,同样的还有CFNetServices;
  • BSD sockets:属于OS层,也是基于C的封装;

框架结构

CFNetwork框架包括的类库如下:
screenshot.png
(图片来源于官方文档)

可以看到,CFNetwork的基础是CFSocket和CFStream。

CFSocket API
Socket是网络通讯的底层基础,可以让两个socket端口互发数据。最常用的socket抽象是BSD socket了。而CFSocket则是BSD socket的抽象,基本上实现了几乎所有BSD socket的功能,并且还融入了run loop。

CFStream API
CFStream API提供了与设备无关的读写数据的方法。使用它可以为内存、文件、网络(使用socket)的数据建立stream,能使用stream而不必马上把所有数据都写入到内存中。

CFStream提供API对两种CFType对象提供抽象:CFReadStream and CFWriteStream。它同时也是CFHTTP和CFFTP的基础。

CFNetwork 版本1

//定义头信息
        CFStringRef headerFieldName = CFSTR("this is a header");
        CFStringRef headerFieldValue = CFSTR("value");

        //创建url
        CFStringRef url1 = CFSTR("http://httpbin.org/get");
        CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, url1, NULL);

        //设置请求方式
        CFStringRef requestMethod = CFSTR("GET");

        //创建请求
        CFHTTPMessageRef myRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault,requestMethod, myURL, kCFHTTPVersion1_1);

        
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值