iOS-NSURLSession的使用

前言

iOS的网络编程,主要围绕NSURLConnection和NSURLSession来进行。iOS7之后NSURLSession才出来,目前看起来NSURLConnection是有被抛弃的迹象,特别是2016年规定的所有网络要支持ipv6,其中竟然没有说到NSURLConnection。
了解一个系统类,需要补充非常多的背景知识,如果没有这些背景知识,很难透彻理解整个类是如何运作的。不过作为api的调用者,往往可以不用管其内部如何实现。Session可以被翻译为会话,两台不同的计算机进行通信的过程,其实就是会话的过程。

三步法请求

学习NSURLSession,免不了要和几个重要的类打交道,比如NSURLSessionConfiguration/NSURLSession/NSURLSessionTask。使用起来,一般都有套路,下面先看看这些套路。

1、请求的URL
2、用URL生成Request,Http请求里面的请求头内容
3、生成Session,将Request作为参数,调用Session的dataWithRequest来发送网络请求

网络请求三步法。对应到代码:

1、NSURL *url = [NSURL URLWithString:@"www.baidu.com/news/hfu3284"];
2、NSURLRequest *request = [NSURLRequest requestWithURL:url];
3、NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithRequest:request] resume];

套路只需要照着用就行了,可以暂时不管为何要按照这些套路来。
了解完基本的使用方式后,就可以根据使用场景来进行说明了。一般app的网络请求里面,http请求占了很大一部分,tcp当然也有不过只在IM或者游戏这样的功能里。下面看看http请求的几个场景:

使用场景

网络编程方面,如果脱离了具体的场景,理解起来特别困难,所有场景都是基于Http的,先了解这些使用场景。Http协议说白了就是两台计算机之间要通信,通信时的一些规则。所有的http请求,要么就是由客户端向服务器请求文件,要么就是客户端向服务器上传文件。

使用场景一:http网络请求

这个一般是业务接口,比如拉取json/xml数据。目前普遍用afnetworking来做。下面这个例子展示了非常简单的http网络请求,可以看到请求头并未拼接参数,稍微复杂一些的网络参数则需要根据是GET还是POST来进行相应处理。


//1、请求字符串
NSString *str = @"http://swiftcafe.io/2015/12/20/nsurlsession/";
//2、转化成url
NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
//3、构建request
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//4、获取session
NSURLSession *session = [NSURLSession sharedSession];
//5、用session发送请求,返回一个dataTask
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (data && (error == nil)) {
        NSLog(@"data=%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    }
    else {
        
        NSLog(@"error=%@",error);
    } }];
//6、dataTask创建后是挂起状态,需要调用resume开启访问
[dataTask resume];

使用场景二:文件下载

文件下载和一般的http请求不同的是task的不一样,文件下载使用的是downloadTask,而且返回的block参数也不同,需要在block中对location进行移动并保存,否则block执行完就会删除下载的文件。

// 1、请求字符串
NSString *str = [NSString stringWithFormat:@"http://swiftcafe.io/2015/12/20/nsurlsession/894.png"];
//2、转化成url
NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
//3、构建request
NSURLRequest *request = [NSURLRequest requestWithURL:url];

//4、获取session
NSURLSession *session = [NSURLSession sharedSession];

//5、用session发送请求,返回一个downloadTask
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (error == nil) {
        //下载成功
        
    } else {
        //下载失败
        
    }
}];

//6、downloadTask创建后是挂起状态,需要调用resume开启访问
[downloadTask resume];
  

使用场景三:文件上传

文件上传则需要用到POST方法,套路其实都很接近,只不过会有一个formData参数需要传入,这个参数就是一些上传文件的NSData。

// 1、请求字符串
NSString *str = [NSString stringWithFormat:@"http://swiftcafe.io/2015/12/20/nsurlsession/thumbnail.php"];
//2、转化成url
NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
//3、构建request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
//4、获取session
NSURLSession *session = [NSURLSession sharedSession];

//5、用session发送请求,返回一个uploadTask
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[NSData dataWithContentsOfFile:@"IMG_0359.jpg"]     completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (error == nil) {
        NSLog(@"upload success:%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    } else {
        NSLog(@"upload error:%@",error);
    }
}];
//6、开始上传
[uploadTask resume];

表单数据上传

表单数据的上传会比较麻烦,需要设置请求体的内容。格式如下:

请求头:
Content-Type:multipart/form-data;boundary=------------1345123513452323412352
请求体:
------------1345123513452323412352--
Content-Disposition:form-data; name="表单控件名"; filename="文件名"
Content-Type:MIME type
数据
--------------1345123513452323412352--


    NSData *imagedata = UIImageJPEGRepresentation(image, 0.7);
    
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost/dashboard/test.php"]];
     [request setHTTPMethod:@"POST"];
     [request setTimeoutInterval:20];
    
    NSMutableData *body = [NSMutableData data];
    
    //设置表单项分隔符
    NSString *boundary = @"---------------------------14737809831466499882746641449";
    
    //设置内容类型
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
    
    //写入图片的内容
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"PIC_DATA1.jpg\"\r\n",@"file"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:imagedata];
    [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    
    //写入尾部内容
    [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    
    [request setHTTPBody:body];

     NSURLSessionUploadTask * uploadtask = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:body completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSString * htmlString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
         NSLog(@"%@", htmlString);
    }];
    [uploadtask resume];

你可能感兴趣的:(iOS-NSURLSession的使用)