iOS网络请求
系列导航
这几天在看关于NSURLSession的相关内容,结果阅看越多,阅看越乱,感觉里边有好多东西啊,又加上AFNetWorking这个三方库,简直头都大了,从头来,仔细分析一下,下边是我自己根据官方文档以及自己的理解所写,不足之处还请多多指教
官方文档
- About the URL Loading System
- Using NSURLSession
- NSURLSession
- NSURLSessionDelegate
- NSURLSessionTaskDelegate
- NSURLSessionDataDelegate
- NSURLSessionDownloadDelegate
简单的来说,请求数据的话,要这么执行
- 要用到NSURLSession这个类,这个类的对象在初始化的时候要配置一下
- 配置的时候就用到这个类NSURLSessionConfiguration
- 这个类有三种配置方式,用缓存等相关技术的,不用缓存相关技术的,可以后台下载的,然后就可以请求数据了
- 请求的时候还要用到NSURLRequest来做一个请求
- 这个请求需要一个URL
- 这个URL可以用字符串转换而来
- 然后请求的时候又分一下几种情况
- 下载
- 上传
- 用GET请求
- 用POST请求
- 用block处理数据
- 用协议代理处理数据
好复杂的说
先分析一下
1.URL Loading System
1.1 下边是官方列举的URL Loading System支持的格式,基本上涵盖了日常使用的所有格式
1. File Transfer Protocol (ftp://)
2. Hypertext Transfer Protocol (http://)
3. Hypertext Transfer Protocol with encryption (https://)
4. Local file URLs (file:///)
5. Data URLs (data://)
1.2 URL Loading System的层级关系
- In iOS 7 and later or OS X v10.9 and later, NSURLSession is the preferred API for new code that performs URL requests.
- –>也就是说,在iOS7之后以及OS X 10.9之后应该用NSURLSession,NSURLConnection已经废弃
- For software that must support older versions of OS X, you can use NSURLDownload to download the contents of a URL to a file on disk.
- –>要是支持老式的OS X 用NSURLDownload去处理下载的流程
- For software that must support older versions of iOS or OS X, you can use NSURLConnection to download the contents of a URL to memory. You can then write the data to disk if needed.
- – iOS和OS X都要支持的话,就用NSURLConnection
1.3 数据传输用到API
- For simple requests, use the NSURLSession API to retrieve the contents from an NSURL object directly, either as an NSData object or as a file on disk.
- –> 如果是简单的请求的话,用NSURLSession来处理任务 NSData写入数据到硬盘
- For more complex requests—requests that upload data, for example—provide an NSURLRequest object (or its mutable subclass, NSMutableURLRequest) to NSURLSession or NSURLConnection.
- –> 如果复杂的话,就要用 NSMutableURLRequest 比如说POST请求,或者其他断点续传之类的
1.4 数据传输的方式
Regardless of which approach you choose, your app can obtain the response data in two ways: 有两种方式可选,取决于你的用途
- Provide a completion handler block. The URL loading class calls that block when it finishes receiving data from the server.
- –> 一种是带block的,当数据传输完成之后,会自动调用block里边的内容去执行,这个一般用来做简单的传输
- Provide a custom delegate. The URL loading class periodically calls your delegate methods as it receives the data from the originating source. Your app is responsible for accumulating that data, if needed.
- –> 一种是用协议代理的方式 在下载的过程过程中不断的调用协议代理的方法,用来处理下载逻辑,比如控制进度条的百分比等等
2.NSURLSession
2.1 NSURLSession的层级关系
继承与NSObject,有下边几个配合类来完成网络请求 . 代表层级关系
![层级关系\
- NSURLSession
- –> 基类,继承与NSObject,没什么好说的
- NSURLSessionConfiguration
- –> 继承与NSObject 用来配置session
- NSURLSessionTask
- –> 继承与NSObject 用来管理相关任务
- NSURLSessionDataTask
- –> 继承与NSURLSessionTask 用来管理data形式的传输
- NSURLSessionUploadTask
- –> 继承与NSURLSessionTask 用来管理数据上传
- NSURLSessionDownloadTask
- –> 继承与NSURLSessionTask 用来管理下载
2.2 NSURLSession的协议的代理
- NSURLSessionDelegate
- –> session总代理
- NSURLSessionTaskDelegate
- –> task总代理 继承与session总代理
- NSURLSessionDataDelegate
- –> data总代理继承与task总代理
- NSURLSessionDownloadDelegate
- –> 下载总代理继承与task总代理
2.3 NSURLSession其他相关辅助类
3.NSURLSessionConfiguration 配置Session的类
用于配置session的一个类,有三种
3.1 defaultSessionConfiguration
默认的配置使用了缓存,cookie,storage,认证等技术,可以满足常用的请求
Modifying the returned session configuration object does not affect any configuration objects returned by future calls to this method, and does not change the default behavior for existing sessions. It is therefore always safe to use the returned object as a starting point for additional customization.
官方数,配置了就不能更改了,改了也没用,貌似时执行了NSCoping协议,所以会无效
3.2ephemeralSessionConfiguration
不使用缓存,cookie,storage,认证等技术,直接写入RAM
in iOS, the in-memory cache is not purged automatically when your app is suspended but may be purged when your app is terminated or when the system experiences memory pressure.
在iOS中,当你的app挂起的时候,可能不会中断,当app关闭或者被系统关闭的时候,链接会中断
3.3backgroundSessionConfigurationWithIdentifier
需要一个唯一标示符
Use this method to initialize a configuration object suitable for transferring data files while the app runs in the background. A session configured with this object hands control of the transfers over to the system, which handles the transfers in a separate process. In iOS, this configuration makes it possible for transfers to continue even when the app itself is suspended or terminated.
If an iOS app is terminated by the system and relaunched, the app can use the same identifier to create a new configuration object and session and retrieve the status of transfers that were in progress at the time of termination. This behavior applies only for normal termination of the app by the system. If the user terminates the app from the multitasking screen, the system cancels all of the session’s background transfers. In addition, the system does not automatically relaunch apps that were force quit by the user. The user must explicitly relaunch the app before transfers can begin again.
当app在后台的时候,用这个来配置session可以实现后台下载,是在另一个线程下载数据
如果app被系统关闭后者重启,那么可以通过唯一标示符来重新创建一个session然后接着下载
如果是用户从多任务界面手动关闭的话,那么就要用户自己去点开app执行相关的下载
(这个我自己理解的也不是很清楚,这两中情况应该是都需要写相关的代码来实现的)
4.数据请求相关方法
上边提到有两种方式请求,一种是通过带completionHandler的block来接受数据,另一种就是不带completionHandler的方法,通过协议代理的方式来完成,下边就是各种情况的相关函数
4.1 Adding Data Tasks to a Session data请求
- dataTaskWithURL:
- dataTaskWithURL:completionHandler:
- dataTaskWithRequest:
- dataTaskWithRequest:completionHandler:
4.2 Adding Download Tasks to a Session 下载请求
- downloadTaskWithURL:
- downloadTaskWithURL:completionHandler:
- downloadTaskWithRequest:
- downloadTaskWithRequest:completionHandler:
- downloadTaskWithResumeData:
- downloadTaskWithResumeData:completionHandler:
4.3 Adding Upload Tasks to a Session 上传请求
- uploadTaskWithRequest:fromData:
- uploadTaskWithRequest:fromData:completionHandler:
- uploadTaskWithRequest:fromFile:
- uploadTaskWithRequest:fromFile:completionHandler:
- uploadTaskWithStreamedRequest:
4.4 Managing the Session 管理session
- finishTasksAndInvalidate
- flushWithCompletionHandler:
- getTasksWithCompletionHandler:
- invalidateAndCancel
- resetWithCompletionHandler:
5.协议代理
5.1 NSURLSessionDelegate的代理方法,这个作为基类,一般用不到
- URLSession:didBecomeInvalidWithError:
- URLSession:didReceiveChallenge:completionHandler:
- URLSessionDidFinishEventsForBackgroundURLSession:
5.2 NSURLSessionTaskDelegate的代理方法
- URLSession:task:didCompleteWithError:
- –>告诉代理,数据传输完成,也就是完成时候调用此方法
- URLSession:task:didReceiveChallenge:completionHandler:
- –> 貌似是基于身份认证改变的时候会调用的方法
- URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:
参数 | 说明 |
---|---|
didSendBodyData 后边的饿参数 | 本次传输发送的数据 |
totalBytesSent 后边的参数 | 到目前为止接收到的数据总和 |
totalBytesExpectedToSend 后边的参数 | 数据的总数 |
- URLSession:task:needNewBodyStream:
- –> Tells the delegate when a task requires a new request body stream to send to the remote server. 告诉代理,收到了一个新的请求体
- URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:
- –> This method is called only for tasks in default and ephemeral sessions. Tasks in background sessions automatically follow redirects.默认的配置或者是ephemeral配置才会调用
5.3 NSURLSessionDataDelegate 的代理方法
URLSession:dataTask:didReceiveResponse:completionHandler:
- –> completionHandler 参数说明,
这个block必须调用
,括号里必须时下边三个枚举值之一
- If you pass NSURLSessionResponseAllow, the task continues normally.
- 继续下载
- If you pass NSURLSessionResponseCancel, the task is canceled
- 取消下载
- If you pass NSURLSessionResponseBecomeDownload as the disposition, your delegate’s URLSession:dataTask:didBecomeDownloadTask: method is called to provide you with the new download task that supersedes the current task.
- 会调用下边的方法
- If you pass NSURLSessionResponseAllow, the task continues normally.
- –> completionHandler 参数说明,
URLSession:dataTask:didBecomeDownloadTask:
- –>告诉代理,task有data变为download
- URLSession:dataTask:didReceiveData:
- –> 告诉代理,收到了数据
- URLSession:dataTask:willCacheResponse:completionHandler:
- –> Asks the delegate whether the data (or upload) task should store the response in the cache. 告诉代理是缓存响应
5.4 NSURLSessionDownloadDelegate 的代理方法
- URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:
- –> 告诉代理,下载重新开始
- URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:
参数 | 说明 |
---|---|
didWriteData后边的参数 | 本次传输接收到的数据的大小 |
totalBytesWritten 后的参数 | 到目前为止接收到的数据总和 |
totalBytesExpectedToWrite 后的参数 | 数据的总字节数 |
- URLSession:downloadTask:didFinishDownloadingToURL:
- –> 必须实现的方法 完成下载的时候调用