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];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容