Github: Jerry4me, Demo: JRBgSessionDemo
This article is mainly combined with official documents, mining NSURLSession class hierarchy and its links, summed up some of the key points of NSURLSession and its usage
About why NSURLSession can replace NSURLConnection, what is its advantage, and its NSURLSession API overview, see
- IOS7 NSURLSession.
New features on ATS, HTTP/2, and iOS9 NSURLSession: sharedCookies, streamTask and taskMetrics, see
- IOS9 ATS HTTP/2 NSURLSession
More than two articles are my watch WWDC videos are then summed up the article, we can be interested in understanding first understand. If you don’t want to know so much, just want to know how to use NSURLSession, it can look directly at the text.
* learn about URL Loading System
- Introduction to NSURLSession related classes
- Authentication and custom TLS
- App Transport Security
- NSURLSession workflow
- Background transmission and its usage
- NSURLSession API
- Other points of attention
- Support data, FTP, HTTP (s) protocol, while supporting the proxy server and socks gateway
- Support http/1.1, http/2, spdy protocol, but also need server support ALPN and NPN.
ALPN and NPN (ALPN Application Layer Protocol Negotiation, application layer protocol negotiation NPN (Next Protocol Negotiation), the next generation of NPN server protocol negotiation) is its support for HTTP protocol list for the client selection; and ALPN is opposite, sent by the client which supports HTTP protocol for server selection list, if the lack of NPN/ALPN. One of them, you can not use the HTTP/2 communication. See why we should as soon as possible to support ALPN.
NSURLSession related classes:
Their mutual relationship is as follows:
Session is divided into:
- Global sharing single case session: NSURLSession sharedSession, there are some limitations
- Custom session: Custom profiles, set up agents, most of the time we are using this
- Background session: is also a custom session, but he is dedicated to do background upload / download tasks
Session for which type is completely determined by its internal Configuration
Configuration is divided into:
- DefaultSessionConfiguration: system default
- EphemeralSessionConfiguration: only memory cache, no disk cache configuration
- BackgroundSessionConfiguration: you need to specify a identifier, identifier is used to re connect the session object. (do background upload / download is this config)
In addition, we can also give some custom Configuration object attributes, such as the maximum concurrent HTTP requests per port number, and whether to allow the cellular network, cache strategy, request timeout, cookies/ certificate storage strategy
Session manages a set of tasks to share an agent and does not want to implement the proxy method when the agent passes nil. The
proxy protocol is divided into:
- NSURLSessionDelegate: session-level proxy method
- NSURLSessionTaskDelegate: task-level oriented all proxy method
- NSURLSessionDataDelegate: upload proxy method for data and task-level
- NSURLSession Download Delegate: task-level oriented download proxy method
- NSURLSessionStreamDelegate: task-level oriented stream proxy method
Session task type is divided into:
- NSURLSessionTask: an abstract base class for Task
- NSURLSessionDataTask: receive a URLRequest content in the form of NSData
- NSURLSessionUploadTask: upload NSData or local disk file, after the completion of the form of NSData to receive a URLRequest response
- NSURLSessionDownloadTask: download the URL path of the temporary file on the local disk after the download is complete
- NSURLSessionStreamTask: used to build a TCP/IP connection
NSURLSessionTaskMetrics and NSURLSessionTaskTransactionMetrics
To send a request to the /DNS query statistics and other link request response time of /TLS. It is easy to shake hands / detection, analysis of our App request is slow in which links, and optimize and improve the performance of our APP.
The NSURLSessionTaskMetrics object corresponds to one of the NSURLSessionTask objects. Each NSURLSessionTaskMetrics object has 3 properties:
- TaskInterval: task total time from start to finish
- RedirectCount: number of task redirects
- TransactionMetrics: a task from the request to each sub process data derived from the received request, it is fitted with a NSURLSessionTaskTransactionMetrics array of many objects. Each object represents a sub process of the
API is very simple, just one way: – (void) URLSession: didFinishCollectingMetrics: task:, when the collection is completed, the method will be called
Authentication and custom TLS
- When a server requires authentication or TLS handshake to provide a certificate, URLSession will call his agent method URLSession: did Receive Challenge: Handler: to deal with
- If you do not realize the agent method, URLSession will do: the use of authentication information as part of the request URL (if available) in the user’s Keychain network to find the password and certificate (in macOS), keychain search in app (in iOS)
- If the certificate is not available or the certificate server refused connection, will continue to lack of authentication for HTTP (S) connection request fails and returns a status code, may provide some alternative content, such as a private website public web. For other URL types (such as FTP), is connected the request failed to return error information directly
App Transport Security
Support ATS from iOS9, and the default ATS only supports sending HTTPS requests, not allowed to send unsafe HTTP requests. If the user needs to send HTTP requests need to configure something in the info.plist
Details of the article at the beginning of the iOS9 ATS HTTP/2 NSURLSession is very detailed, want to know can go in to read
So how do you use NSURLSession to send a request like NSURLConnection?
Configure NSURLSessionConfiguration *config = [NSURLSessionConfiguration / defaultSessionConfiguration]; / * * set other configuration properties **/ / / NSOperationQueue *queue = [NSOperationQueue mainQueue] agent queue; / / create session NSURLSession *session = sessionWithConfiguration:config delegate:self [NSURLSession delegateQueue:queue] n task NSURLSessionDownloadTask; / / create *task = [session downloadTaskWithURL:[NSURL URLWithString:@ https://www.baidu.com "by session [task resume]; / / to;
Then you can deal with a variety of things in the proxy method. Simple? The following sub task description of the proxy method
Authentication or TLS handshake
This is a process that all task must go through. When a server authentication request or during the TLS handshake need to provide the certificate, URLSession will call his agent URLSession: did method Receive Challenge: completion Handler:. To deal with, in addition, if the connection way received the identity authentication server returns response that will call the agent.
Which is a process of all task are likely to experience, if response is HTTP positioning, session will call the URLSession: task: agent will Perform HTTPRedirection: new Request: completion Handler:. Here you need to call the completionHandler tell session whether to allow or relocation, relocation to another URL or, nil said in response to body relocation effectively and return. If the agent did not realize this method allows the relocation relocation until you reach the maximum number.
- For a data task, session will call the URLSession: data agent Task: did Receive Response: completion Handler: method, to decide whether to put a data dask into download task, and then call the completion callback continues to receive the data or download the data. if you choose app into download task, session call URLSession: data agent Task: did Become Download Task: and the new download task object as method parameters transmitted to you. After the agent will not receive data task back to download task but received the callback
- When the server transmits data to the client, the agent periodically receives a URLSession: data Task: Receive Data: callback
- Session will call the URLSession: data Task: will Cache Response: completion Handler: app asked you whether to allow the cache. If the agent does not realize it, use the default caching strategy session bound Configuration.
- For a download Task created by With Resume Data: download task, session will call the URLSession: download agent Task: did Resume At Offset: expected Total Bytes: method.
- In the server to the client during the transmission of data, called URLSession: download Task: did Write Data: total Bytes Written: total Bytes Expected To Write: data transfer to the user when the user pauses for download, call cancel By Producing Resume Data: to transfer user data has been good. If the user wants to resume the download, just resumeData in the form of parameters passed to the download Task With Resume Data: method to create a new task to download.
- If the successful completion of the download task, URLSession: download Task: called did Finish Downloading To URL: the path to the temporary URL files for you. Then you should read his data before returning to the agent or the method of file persistence.
During the upload data to the server, the agent will periodically receive URLSession: task: did Send Body Data: total Bytes Sent: total Bytes Expected To Send: callback and get the upload progress report.
If the task of the data is sent by a stream, session will call the URLSession: task: agent need New Body Stream: method to obtain a NSInputStream object and provides a new request for body data.
Whenever a task is completed, it will be invoked by the URLSession: task: Complete With Error: method, and error has the potential for nil (request success), not for nil (request failure) (did)
- The request failed, but the task is to resume the download, then there is a NSURLSession Download Task Resume Data value error userInfo of the corresponding object in the dictionary, you should put this value to the download Task With Resume Data: method to recover under load
- The request failed, but the task could not be restored, so you should create a download task and download it from scratch
- Create and restore requests for other reasons (such as server errors, etc.)
NSURLSession will not receive from the server, client agent will only receive errors, such as unable to resolve the host name or not connected to the host. The client error definition for transmission in the URL Loading System Error Codes. HTTP server errors by state law, see NSHTTPURLResponse and NSURLResponse.
If you no longer need a session, we must call it invalidateAndCancel or finishTasksAndInvalidate. (the former is canceled all the unfinished tasks and then disable the session, the latter is after waiting for the mission to complete the session failure). Otherwise, it may cause memory leaks. In addition, session failure will we call the URLSession: did Become Invalid With Error:, after session on the release of agent strong references.
It should be noted that, in the background of session, some proxy methods will fail. Here are some of the notes that use the background session:
- Background session must provide an agent to handle unexpected events
- Only supports the HTTP (S) protocol and other protocols are not available
- Only support upload / download tasks, data tasks are not supported
- Background tasks have a number of restrictions
- When the system is specified when the number reaches a critical value of the task, some background tasks will be cancelled. That is to say, a long time to upload / download task is likely to be cancelled and then later system may start again, so the HTTP support is very important.
- If a task is in the background transmission app open in the background of the time, then the task is likely due to performance considerations be canceled. System. (the discretionary property is equivalent to the session Configuration object true.)
Background session restrictions do a lot, so as far as possible the use of foreground session do things
Note background session best to transfer some support for HTTP file. Or on the process of some specific optimization best file first compressed into zip/tar compressed files to upload / download. The large files as data segments are sent, sent after the server to upload data together. When the server should return an identifier that can track the transmission state, make timely adjustments to increase the transmission of a web proxy server layer, in order to promote the optimization
So how do you use this background transfer?
- Create a background session NSURLSessionConfiguration *config backgroundSessionConfigurationWithIdentifier:@ [NSURLSessionConfiguration = “com.Jerry4me.backgroundSessionIdentifier”]; _backgroundSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
- Create a upload or download task NSURL *URL [NSURL URLWithString:@ = “http://www.bz55.com/uploads/allimg/140402/137-140402153504.jpg”]; NSURLRequest *request = [NSURLRequest requestWithURL:URL] = [self.session; self.task downloadTaskWithRequest: request]; / * * Note: background tasks cannot be used with the completionHandler method to create **/ / * * Note: if the task was processed in app just want to enter the background, you can not call the [task resume] initiative the execution, until the program will automatically enter the background **/
- We downloaded to the half into the background, open the App Switcher later can be found after the download pictures will be displayed on the application. The method call order: the following four methods are all in the background of the app call
2017-03-24 14:17:09.458415 JRBgSessionDemo[2766:1080861] 2017-03-24 14:17:09.567957 JRBgSessionDemo[2766:1080861] 58% download - Download - 59% 2017-03-24 14:17:16.916830 JRBgSessionDemo[2766:1080828] -[AppDelegate application: handleEventsForBackgroundURLSession:completionHandler:] 2017-03-24 14:17:16.951185 JRBgSessionDemo[2766:1080977] -[DownloadViewController URLSession:downloadTask:didFinishDownloadingToURL:] 2017-03-24 14:17:16.953951 JRBgSessionDemo[2766:1080977] DownloadViewController URLSession:task:didCompleteWithError:] 2017-03-24 14:17:16.954574 JRBgSessionDemo[2766:1080977] - -[DownloadViewController URLSessionDidFinishEventsForBackgroundURLSession:]
Summary background transfer
- Try to use the real machine debugging, the simulator will skip some one or two methods
- Only upload/download task can not be carried out data task
- CompletionHandler can not be used with the method of creating task, otherwise the program directly hang
- Applecation in the completionHandler must be stored, and so you have to deal with all the things you can call again after the system can be Snapshot and app
- Download the best support HTTP, because the task may be cancelled (such as system of system performance, resources are not enough case)
The background of the transfer of Demo in the head of the article, you can also click here
- Create Session + session With Configuration: Torgovnik: create a specified configuration of session + session With Configuration: delegate: delegate Torgovnik Torgovnik Queue: Torgovnik: create a specified configuration, proxy and proxy method execution queue session shared Session return session: single case
- Configure Session configuration: configure delegate: proxy object delegateQueue: proxy method execution queue sessionDescription: app defined for the description of the session
- Add data task – dataTaskWithURL:: access to the specified URL content – dataTaskWithURL:completionHandler:: Specifies the contents of the URL processing in completionHandler data. This method can bypass the proxy method (except proxy method authentication challenge) – data Task With Request: Torgovnik: access to the specified URLRequest content – data Task With Request: Torgovnik completionHandler:: Specifies the contents of the URLRequest processing in completionHandler data. This method can bypass the proxy method (except proxy method authentication challenge)
- Add download task – downloadTaskWithURL:: download the specified URL content – downloadTaskWithURL:completionHandler:: download the specified URL content in completionHandler data processing. This method can bypass the proxy method (except proxy method authentication challenge) – downloadTask With Request: Torgovnik: URLRequest – downloadTask to download the specified content With Request: Torgovnik completionHandler:: download the specified the URLRequest content in completionHandler data processing. This method can bypass the proxy method (except proxy method authentication challenge) – downloadTask With ResumeData: Torgovnik: create a cancellation / download before the failure of download task – downloadTask With ResumeData: Torgovnik completionHandler:: create a before cancellation / download failed download task, in complet Processing data in ionHandler. This method bypasses the proxy method (in addition to the proxy method for authentication challenges)
- Add upload upload Task With – Request: from Data: Torgovnik Torgovnik: URL – upload to the specified Task With Request: Torgovnik from Data:completionHandler: request data by HTTP: data sends request to the specified by HTTP URL, in completionHandler data processing. This method can bypass the proxy method (except the method of identity authentication challenge) – upload Task With Request: from File: Torgovnik Torgovnik: specify the file to the specified URL upload Task With Request: from File: completionHandler: Torgovnik request sent by HTTP: the HTTP request sent through the specified file to the specified URL, the data processing in completionHandler. The method will bypass the proxy method (except proxy method authentication challenge) upload Task With StreamedRequest via a HTTP request to: Set the URLRequest data stream to the specified URL
- Add stream – streamTask With HostName:port: task Torgovnik: the given domain name and port to establish two-way TCP/IP connection – streamTask With NetService:: connected by given network service to establish bidirectional TCP/IP
- Session finishTasksAndInvalidate: the task completed after the destruction of session flushWithCompletionHandler:: remove cookies and certificate on the hard disk, clean up temporary cache, to ensure that the future can respond to a new TCP request getTasksWithCompletionHandler:: asynchronous transfer session in all upload, download, data tasks completion. InvalidateAndCancel callback: cancel all unfinished tasks and destroy the session resetWithCompletionHandler:: clear cookies, cache and certificate storage, remove all disk files, cleaning is performed to ensure that the future can download tasks in response to a new socket request
All create a task method with completionHandler as long as this parameter, said method is not triggering the proxy request process. All the parameters with completionHandler, will go proxy process.
If you implement the URLSession: did Challenge: completion Handler: method and there is no call in the completionHandler method, the request will be blocked by the Receive
HTTP download failed / pause / cancelled, can save the downloaded data by task – cancel By Producing Resume Data: method, and then call session download Task With Resume Data:, URLSession: download trigger agent Task: did Resume At Offset: I expected Total Bytes: method
Something else Important
Session, task, and configuration objects all support copy operations:
- Session/task copy: returns the session object itself
- Configuration copy: returns an object that cannot be modified (immutable)
URLSession’s API is all thread safe. You can create session and tasks on any thread, and task will automatically be dispatched to the appropriate proxy queue
The method of Warning transmission URLSession Did background Finish Events For Background URLSession: may be invoked in other threads. In this method, you should go back to the main thread and then call the completion handler in the application: to trigger the AppDelegate handle Events For Background URLSession: completion Handler: method..
- NSURLSession-Specific NSError Info Dictionary Keys: NSURLSession API appears in the NSError userInfo of keys user
- Background Task reasons Cancellation: indicating why the system has canceled your back office tasks
- Transfer Size Constant: indicates an unknown transfer size constant
NSURLSession Foundation –
WWDC 2013 – Session 204 – What’s New with Multitasking
WWDC 2013 – Session 705 – What’s New in Foundation Networking
WWDC 2015 – Session 711 – Networking with NSURLSession
WWDC 2016 – Session 711 – NSURLSession: New Features and Best Practices