Preface:
Both Android and iOS cannot do without interaction with the server, so network requests must be used. Remember when I was working on iOS in 2013, I used the ASIHTTPRequest framework. Now when I picked up iOS again, ASIHTTPRequest has stopped maintaining it. Everyone is using AFNetWorking as the preferred network request framework. The previous ASIHTTPRequest was implemented based on the NSURLConnection class. The early AFNetWorking was also implemented based on the NSURLConnection. Later, iOS9 gave up NSURLConnection and started using the NSURLSession launched after iOS 7. Based on the principle of tracing the root cause, first learn the implementation of NSURLSession network requests, and then learn AFNetWorking.
Understand NSURLSession
NSURLSession was released in 2013 to replace NSURLConnection. After iOS 9, NSURLConnection completely launched the historical stage. It is very convenient to use. Today, NSURLConnection uses NSURLConnection to implement get, post, form submission, file upload, and file download, which amazed me, a programmer who mainly develops Android. Create a request task based on the NSURLSession session object, and then execute the task, including cache and session cycle. iOS has been encapsulated at the SDK level. Unfortunately, NSURLSession only provides asynchronous request methods but does not provide synchronous request methods. Next, let’s see how to implement network requests.
NSURLSession usage
Let's start with a simple get request as an example.
1.) First construct an NSURL request resource address
// Construct URL resource address NSURL *url = [NSURL URLWithString:@/method?name=yanzhenjie&pwd=123];
2.) Create an NSRequest request object
// Create a Request request NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // Configure Request Request // Set the request method [request setHTTPMethod:@"GET"]; // Set request timeout Default timeout 60s [request setTimeoutInterval:10.0]; // Set head parameters [request addValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; // Or add all request header information in the following way =@{@"Content-Encoding":@"gzip"}; //Set the cache policy [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
Add unnecessary settings according to your needs, such as request method, timeout time, and request header information. Here we will introduce the cache strategy:
- NSURLRequestUseProtocolCachePolicy = 0 //Default cache policy, if the cache does not exist, it will be obtained directly from the server. If the cache exists, the next operation will be judged based on the Cache-Control field in the response. For example: The Cache-Control field is must-revalidata, then the server will be asked whether the data has been updated. If there is no update, it will be directly returned to the user for cached data. If it has been updated, the server will be requested.
- NSURLRequestReloadIgnoringLocalCacheData = 1 //Ignore local cached data and directly request the server.
- NSURLRequestIgnoringLocalAndRemoteCacheData = 4 //Ignore local cache, proxy server and other intermediaries and directly request the source server.
- NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData
- NSURLRequestReturnCacheDataElseLoad = 2 //If there is a cache, use it regardless of its validity (i.e. ignore the Cache-Control field), if there is no, the server will be requested.
- NSURLRequestReturnCacheDataDontLoad = 3 //Only load local cache. If not, fail. (Confirm that there is no network currently)
- NSURLRequestReloadRevalidatingCacheData = 5 //Cached data must be confirmed by the server before it can be used
3.) Create NSURLSession session object
You can share the Session by using iOS
// Use the shared session provided by Apple NSURLSession *sharedSession = [NSURLSession sharedSession];
Different NSURLSessions can be configured through NSURLSessionConfiguration
// Construct NSURLSessionConfiguration NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; // Construct NSURLSession, network session; NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
NSURLSessionConfiguration provides three ways to create NSURLSession
- defaultSessionConfiguration //The default configuration uses a persistent hard disk cache, storing certificates to user key chains. Store cookies to shareCookies.
- ephemeralSessionConfiguration //Do not use permanently persisted cookies, certificates, and cache configurations to optimize data transmission.
- backgroundSessionConfigurationWithIdentifier //You can upload and download background tasks for HTTP and HTTPS (the program runs in the background).
In the background, the network transmission is handed over to a separate process of the system, and even if the app is suspended, launched or even crashed, it will still be executed in the background.
You can also set the timeout time, request header and other information through NSURLSessionConfiguration.
// Construct NSURLSessionConfiguration NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; //Set the request timeout to 10 seconds = 10; //Whether to continue requesting (upload or download) in the case of cellular network = NO; //Configure the request header =@{@"Content-Encoding":@"gzip"};
4.) Create an NSURLSessionTask object and execute it
// Construct NSURLSessionTask, session task; NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // Request failed, print error message if (error) { NSLog(@"get error :%@",); } //The request is successful, the data is parsed else { // JSON data format analysis id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error]; // Determine whether the parsing is successful if (error) { NSLog(@"get error :%@",); }else { NSLog(@"get success :%@",object); // The parsing is successful, the data is processed, the main queue is obtained through GCD, and the interface is refreshed in the main thread. dispatch_async(dispatch_get_main_queue(), ^{ // Refresh the interface... }); } } }];
In order to adapt to different application scenarios, iOS provides different types of NSSessionTasks
- NSURLSessionDataTask //General requests for get, post, etc.
- NSURLSessionUploadTask // Used to upload files or requests with large amount of data
- NSURLSessionDownloadTask // Used to download files or requests with relatively large data volume
- NSURLSessionStreamTask //Create a TCP/IP connection host name and port or a network service object.
Three functions of task
- - (void)suspend;//Suspend
- - (void)resume;//Start or resume
- - (void)cancel;//Close the task
NSURLSession other request examples
1.) Post request
// 1. Create URL resource address NSURL *url = [NSURL URLWithString:@"/postBody"]; // 2. Create a Request request NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 3. Configure Request // Set request timeout [request setTimeoutInterval:10.0]; // Set the request method [request setHTTPMethod:@"POST"]; // Set head parameters [request addValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; // 4. Construct request parameters // 4.1. Create dictionary parameters and put the parameters into the dictionary can prevent programmers from making mistakes in subjective consciousness, that is, the parameters are written incorrectly. NSDictionary *parametersDict = @{@"name":@"yanzhenjie",@"pwd":@"123"}; // 4.2. Iterate through the dictionary and create parameter strings in the way of "key=value&". NSMutableString *parameterString = [[NSMutableString alloc]init]; int pos =0; for (NSString *key in ) { // Stitching strings [parameterString appendFormat:@"%@=%@", key, parametersDict[key]]; if(pos<-1){ [parameterString appendString:@"&"]; } pos++; } // 4.3. Convert NSString to NSData data type. NSData *parametersData = [parameterString dataUsingEncoding:NSUTF8StringEncoding]; // 5. Set request message [request setHTTPBody:parametersData]; // 6. Construct NSURLSessionConfiguration NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; // 7. Create a network session NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration]; // 8. Create a session task NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // 10. Determine whether the request is successful if (error) { NSLog(@"post error :%@",); }else { // If the request is successful, the data is parsed. id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error]; // 11. Determine whether the analysis is successful if (error) { NSLog(@"post error :%@",); }else { // The parsing is successful, the data is processed, the main queue is obtained through GCD, and the interface is refreshed in the main thread. NSLog(@"post success :%@",object); dispatch_async(dispatch_get_main_queue(), ^{ // Refresh the interface... }); } } }]; // 9. Execute tasks [task resume];
2.) Upload the file with form parameter
NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0]; NSTimeInterval a=[dat timeIntervalSince1970]; NSString* fileName = [NSString stringWithFormat:@"file_%", a]; [FileUtils writeDataToFile:fileName data:[@"upload_file_to_server" dataUsingEncoding:NSUTF8StringEncoding]]; // Upload in streaming mode, the size is theoretically not limited, but attention should be paid to time // 1. Create URL resource address NSURL *url = [NSURL URLWithString:@"/upload"]; // 2. Create a Request request NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 3. Configure Request //Set Body value method 2. This method is relatively primitive and not commonly used, but can be used to upload parameters and files NSString *BOUNDARY = @"whoislcj";//Form Dividing Line You can customize any value [request setValue:[@"multipart/form-data; boundary=" stringByAppendingString:BOUNDARY] forHTTPHeaderField:@"Content-Type"]; // Use post to upload files [request setHTTPMethod:@"POST"]; // Set request timeout [request setTimeoutInterval:30.0f]; // Used to store binary data streams NSMutableData *body = [NSMutableData data]; //Add a normal form parameter name=yanzhenjie NSString *nameParam = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n",BOUNDARY,@"name",@"yanzhenjie",nil]; [body appendData:[nameParam dataUsingEncoding:NSUTF8StringEncoding]]; //Add a normal form parameter pwd=123 NSString *pwdParam = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n",BOUNDARY,@"pwd",@"123",nil]; [body appendData:[pwdParam dataUsingEncoding:NSUTF8StringEncoding]]; //Add a file form parameter // Content-Disposition: form-data; name="<name that needs to be known on the server side>"; filename="<filename that is uploaded on the server side>" // Content-Type: application/octet-stream --Select different values according to different file types NSString *file = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\";filename=\"%@\"\r\nContent-Type: application/octet-stream\r\n\r\n",BOUNDARY,@"headUrl",fileName,nil]; [body appendData:[file dataUsingEncoding:NSUTF8StringEncoding]]; //Get file path NSString *filePath =[FileUtils getFilePath:fileName]; NSData *data =[NSData dataWithContentsOfFile:filePath]; //Add file binary data [body appendData:data]; [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; //End the dividing line NSString *endString = [NSString stringWithFormat:@"--%@--",BOUNDARY]; [body appendData:[endString dataUsingEncoding:NSUTF8StringEncoding]]; // Create a session NSURLSession *session = [NSURLSession sharedSession]; // 3. The body data that starts uploading request will be ignored and provided by fromData NSURLSessionUploadTask *uploadTask= [session uploadTaskWithRequest:request fromData:body completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { NSLog(@"upload error:%@",error); } else { NSLog(@"upload success:%@", [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error]); dispatch_async(dispatch_get_main_queue(), ^{ // Refresh the interface... }); } }]; //Execute tasks [uploadTask resume];
3.) File download
// Create url NSString *urlStr =@"/blog/950883/201701/"; NSURL *Url = [NSURL URLWithString:urlStr]; // Create a request NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:Url]; // Set request timeout [request setTimeoutInterval:30.0]; // Create a session NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDownloadTask *downLoadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (!error) { NSLog(@"download sucess : %@", location); NSData *data=[NSData dataWithContentsOfURL:location]; UIImage *image=[UIImage imageWithData:data]; dispatch_async(dispatch_get_main_queue(), ^{ // Refresh the interface... UIImageView *imageView =[[UIImageView alloc]init]; =image; [ addSubview:imageView]; [imageView mas_makeConstraints:^(MASConstraintMaker *make) { (); .mas_equalTo(CGSizeMake(300, 300)); }]; }); } else { NSLog(@"download error : %@", ); } }]; //Start the task [downLoadTask resume];
Summarize:
Today I learned how to implement network requests in the underlying iOS. For development efficiency, I have to rely on an excellent third-party open source framework. The above is the entire content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support me more.