[OC] NSURLSession, ocnsurlsession
Some programmers are old and have never heard of NSURLSession. Some programmers are still young. They have never used NSURLConnection. Some programmers are simple. They only know AFN.
NSURLConnection was declared obsolete in iOS9, and the development of NSURLSession from the past 13 years has finally ushered in its own age. NSURLSession is a series of interfaces provided by Apple for HTTP data transmission after iOS7. It is more powerful than NSURLConnection and has fewer pitfalls and is easy to use. today, we will introduce it from the perspective of usage.
BesidesNSURLSession, Which will appear frequently in the textNSURLSessionConfigurationAndNSURLSessionTaskThere are two types. First, get familiar with each other.
When using NSURLSession, two steps are taken:
- Step 1: create a task through an instance of NSURLSession
- Second, execute the task
Now that task appears in both steps, let's talk about it first.
NSURLSessionTask can be simply understood as a task, such as a data request task, a download task, an upload task, and so on. We use its subclass:
- NSURLSessionTask (abstract class)
- NSURLSessionDataTask
- NSURLSessionDownloadTask
From the names of these sub-classes, we can probably guess their functions. Next we will start from a different type of task to use the session.
NSURLSessionDataTask
It is a data-related task, but in fact, dataTask is fully qualified for downloadTask and uploadTask. This may be the most commonly used task type.
Simple GET request
If the requested data is relatively simple and you do not need to perform complex operations on the returned data, you can use
// Obtain the session object NSURLSession * session = [NSURLSession sharedSession]; NSURL * url = [NSURL URLWithString: @ "http://www.daka.com/login? Username = daka & pwd = 123 "]; // initialize a task through a URL. The returned data can be directly processed inside the block. NSURLSessionTask * task = [session dataTaskWithURL: url completionHandler: ^ (NSData * data, NSURLResponse * response, NSError error) {NSLog (@ "% @", [NSJSONSerialization JSONObjectWithData: data options: kNilOptions error: nil]);}]; // start the task [task resume];Tips:
- All types of tasks must call the resume method to start the request.
Simple POST request
The difference between POST and GET lies in the request. Therefore, the POST request and GET process using the session are the same. The difference lies in the processing of the request.
NSURL * url = [NSURL URLWithString: @ "http://www.daka.com/login"]; NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL: url]; request. HTTPMethod = @ "POST"; request. HTTPBody = [@ "username = daka & pwd = 123" dataUsingEncoding: NSUTF8StringEncoding]; NSURLSession * session = [NSURLSession sharedSession]; // because the request must be processed first, we initialize taskNSURLSessionTask * task = [session dataTaskWithRequest: request completionHandler: ^ (NSData * data, NSURLResponse * response, NSError * error) {NSLog (@ "% @", [NSJSONSerialization JSONObjectWithData: data options: kNilOptions error: nil]) ;}]; [task resume];NSURLSessionDataDelegate proxy method
NSURLSession provides a simple way to process returned data in block mode. However, if you want to further process the received data, you can still call related Protocol methods. the proxy method of the NSURLSession is similar to that of the NSURLConnection, which is divided into several stages: receiving response, receiving data, and completing the request.
// You need to set the proxy when using the proxy method, but the delegate attribute of the session is read-only. To set the proxy, you can only create sessionNSURLSession * session = [NSURLSession sessionWithConfiguration: [NSURLSessionConfiguration defasessessionconfiguration] del: self delegateQueue: [[NSOperationQueue alloc] init]; // create a task (because you do not need block initialization to use the proxy method) NSURLSessionDataTask * task = [session dataTaskWithRequest: [NSURLRequest requestWithURL: [NSURL URLWithString: @ "http://www.d Aka.com/login? UserName = daka & pwd = 123 "]; // start the task [task resume]; // the corresponding proxy method is as follows: // 1. response received from the server-(void) URLSession :( NSURLSession *) session dataTask :( NSURLSessionDataTask *) dataTask didReceiveResponse :( NSURLResponse *) response completionHandler :( void (^) (response )) completionHandler {// The completionHandler (NSURLSessionResponseAllow) returned by the server will be received only after the server can process the server's response.} // 2. received server data (may be called multiple times)-(void) URLSession :( NSURLSession *) session dataTask :( NSURLSessionDataTask *) dataTask didReceiveData :( NSData *) data {// process the data received each time} // 3. request succeeded or failed (if failed, error has a value)-(void) URLSession :( NSURLSession *) session task :( NSURLSessionTask *) task didCompleteWithError :( NSError *) error {// request completed, processing successful or failed}
Tips:
The key points are mentioned in the code comments. The important points are as follows:
- If you want to use the proxy method, you need to set the proxy, but the NSURLSession header file finds that the session's delegate attribute is read-only. Therefore, you need to assign a value through the session Initialization Method when setting the Proxy:
sessionWithConfiguration:delegate:delegateQueue:Where:
- The configuration parameter (as mentioned at the beginning of this article) needs to pass a configuration. We will use the default configuration for the moment.
[NSURLSessionConfiguration defaultSessionConfiguration](I will explain why this configuration is used later );
- The delegateQueue parameter indicates the queue in which the Protocol method will be executed.
- When the NSURLSession receives a response, it must first allow the response:
completionHandler(NSURLSessionResponseAllow);To continue receiving the data returned by the server. it is worth mentioning that if you need to process the returned parameters (such as obtaining the response header information) when receiving a response, these processes should be placed before the operations allowed.
NSURLSessionDownloadTask
You can use the NSURLSessionDownloadTask subclass to download files.
Simple download
NSURLSessionDownloadTask also provides two methods to initialize and callback through NSURL and NSURLRequest. The following uses NSURL initialization as an example:
NSURLSession * session = [NSURLSession sharedSession]; NSURL * url = [NSURL URLWithString: @ "http://www.daka.com/resources/image/icon.png"]; NSURLSessionDownloadTask * task = [session downloadTaskWithURL: url completionHandler: ^ (NSURL * location, NSURLResponse * response, NSError * error) {// location is a temporary url in the tmp folder in the sandbox. The file will be saved to this location after being downloaded, because the files in tmp may be deleted at any time, we need to move the downloaded files to the desired NSString * path = [[NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent: response. suggestedFilename]; // cut the file [[NSFileManager defaultManager] moveItemAtURL: location toURL: [NSURL fileURLWithPath: path] error: nil] ;}]; // start the task [task resume];
Tips:
- Note that you need to transfer the file downloaded to the tmp folder to the desired directory because it has been pasted in the code.
response.suggestedFilenameIs the last part of the storage path from the corresponding file on the server. For example, if the url of the data on the server ishttp://www.daka.com/resources/image/icon.pngSuggestedfilenamepolicicon.png.
NSURLSessionDownloadDelegate proxy method
Similarly, downloadTask also provides a supporting proxy method.
// Every write call (multiple calls will be called)-(void) URLSession :( NSURLSession *) session downloadTask (Bytes *) downloadTask didWriteData :( int64_t) bytesWritten totalBytesWritten :( int64_t) totalBytesWritten progress :( int64_t) progress {// you can calculate the download progress CGFloat SS = 1.0 * totalBytesWritten/totalBytesExpectedToWrite; NSLog (@ "% f ", progress);} // call the download completed-(void) URLSession :( NSURLSession *) session downloadTask :( NSURLSessionDownloadTask *) downloadTask didFinishDownloadingToURL :( NSURL *) location {// location is a temporary path, NSString * filePath = [NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent: downloadTask. response. suggestedFilename]; [[NSFileManager defaultManager] moveItemAtURL: location toURL: [NSURL fileURLWithPath: filePath] error: nil];} // task completion call-(void) URLSession :( NSURLSession *) session task :( NSURLSessionTask *) task didCompleteWithError :( NSError *) error {}
NSURLSessionUploadTask
In NSURLSession, there are two main file upload methods:
NSURLSessionUploadTask * task = [[NSURLSession sharedSession] uploadTaskWithRequest: request fromFile: fileName completionHandler: ^ (NSData * data, NSURLResponse * response, NSError * error) {}]; and. session uploadTaskWithRequest: request fromData: body completionHandler: ^ (NSData * data, NSURLResponse * response, NSError * error) {NSLog (@ "------- % @", [NSJSONSerialization JSONObjectWithData: data options: kNilOptions error: nil]) ;}];
In terms of security, we usually use the POST method for file upload, So we usually use the second method.
However, NSURLSession does not provide a more convenient File Upload method than NSURLConnection.bodyYou must enter the request body (a long string in the format specified by the http protocol ). because you are 90% likely to use AFNetworking, even if you write it yourself, it should be copy, so the code will not be pasted. We just say that the method is great.
Breakpoint download
NSURLSessionDownloadTask provides several methods related to resumable download:
// Use this method to cancel the download and obtain the data to be restored in the future. Save it as [self. task cancelByProducingResumeData: ^ (NSData * resumeData) {self. resumeData = resumeData ;}]; // download interruption due to download failure will enter this Protocol method, and you can also get the data to be restored-(void) URLSession :( NSURLSession *) session task :( NSURLSessionTask *) task didCompleteWithError :( NSError *) error {// save recovery data self. resumeData = error. userInfo [NSURLSessionDownloadTaskResumeData];} // resume the stored recovery data self. task = [self. session downloadTaskWithResumeData: self. resumeData]; // start the task [self. task resume];
Currently, I understand NSURLSession. This type of resumable download only supports intra-application breakpoints. If the program is closed midway through the download process, the download cannot be resumed. (The NSURLSession is not fully understood for the time being, so I am not afraid to let it go. If there is anything wrong, you can communicate with me)
Others
In addition, tasks have the following methods:
- (void)suspend;- (void)resume;- (void)cancel;
Suspend can suspend the current task
The resume method can not only start a task, but also wake up a task in the suspend state.
The cancel method can cancel the current task. You can also send a cancel message to a task in the suspend State. If the task is canceled, it cannot be restored to the previous state.
NSURLSessionConfiguration
In short, it is the session configuration information. For example:
NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration]; // timeout config. timeoutIntervalForRequest = 10; // whether to allow the use of the cellular network (background transmission is not applicable) config. allowsCellularAccess = YES; // you can set many other attributes.
Have you found that all the configurations we use are default configurations:[NSURLSessionConfiguration defaultSessionConfiguration]In fact, there are three types of Configuration:
+ (NSURLSessionConfiguration *)defaultSessionConfiguration;+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier
It indicates several different working modes of NSURLSession.
The default configuration stores the cache on the disk. The second instantaneous session mode does not create a persistent storage cache. The third background session mode allows the program to upload and download files in the background.
In addition to the support for task pause and resumable data transfer, I think the greatest progress of NSURLSession in NSURLConnection is the support for background upload and download tasks. This is another topic that can be discussed in depth. however, I have not conducted any in-depth research in this regard. I will post it later.
PS: AFNetWorking has a series of NSURLSession-based packages since version 2.0. If you are interested, go to learn about them.
Text/CoderAO (simplified author)
Link: http://www.jianshu.com/p/fafc67475c73