【古董】NSURLConnection 发送网络请求

对于现在刚进入 iOS 开发的程序猿来说,可能对于 NSURLConnection 这个古董鲜为人知,在 iOS9.0 之后,苹果官方已经不推荐使用了,但是学无止境,大家可以看看了解一下。针对苹果目前推崇的 NSURLSession,请关注后续更新。

在使用 NSURLConnection 进行网络请求的时候有很多种方法,包括有:GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT、PATCH,其中最常用的就是 GET 请求和 POST 请求。

NSURLConnection 发送请求

GET 请求与 POST 请求的区别:

  • 主要区别在数据传递上
  • GET 在请求 URL 后面以 ?形式跟上发给服务器的参数,多个参数之间用 & 隔开,并且 URL 的长度有限制,通常不超过 1KB
  • POST 发给服务器的参数全部放在请求体中,理论上没有限制
  • 如何选择:
    • 如果要传递大量数据,比如文件上传,只能用 POST
    • GET 的安全性差,如果传递机密信息,使用 POST
    • 如果仅仅是数据查询,建议使用 GET
    • 如果是增删改使用 POST

网络响应的状态

  • 200 OK 请求成功
  • 400 Bad Request 客户端请求语法错误,服务器无法解析
  • 404 Not Found 服务器找不到资源
  • 500 Internal Server Error 服务器内部错误,无法完成请求

发送同步 GET 请求

  1. 确定请求路径(使用 GET 请求时,请求的参数放在路径中)
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520&pwd=520&type=JSON"];
  1. 创建请求对象(默认情况下就是 GET 请求)
NSURLRequest *request = [NSURLRequest requestWithURL:url];
  1. 发送同步请求
NSURLResponse *response = nil;
    NSError *error = nil;
    /**
     第一个参数:请求对象
     第二个参数:响应(头)
     第三个参数:错误信息
     返回值:响应体
     */
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
  1. 解析服务器返回的数据
NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

发送异步 GET 请求

  1. 确定请求路径(使用 GET 请求时,请求的参数放在路径中)
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520&pwd=520&type=JSON"];
  1. 创建请求对象(默认情况下就是 GET 请求)
NSURLRequest *request = [NSURLRequest requestWithURL:url];
  1. 发送异步请求
  2. 解析服务器返回的数据
/**
     第一个参数:请求对象
     第二个参数:操作队列->(线程) 决定completionHandler回调在哪个线程中处理(主队列->主线程)
     第三个参数:completionHandler回调 完成之后的回调
                response:响应头信息
                data:响应体信息
                connectionError:错误信息
     */
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        //4.解析服务器返回的数据
        NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    }];

使用代理发送异步 GET 请求

  1. 确定请求路径(使用 GET 请求时,请求的参数放在路径中)
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520&pwd=520&type=JSON"];
  1. 创建请求对象(默认情况下就是 GET 请求)
NSURLRequest *request = [NSURLRequest requestWithURL:url];
  1. 设置请求代理,遵守协议
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

注意: 协议使用的是NSURLConnectionDataDelegate

补充: 以上设置代理会立即发送请求,如要控制是否立即发送,可以使用以下方法并调用 start 手动发送网络请求

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[connection start];
  1. 实现代理方法
    • 设置代理发送 GET 请求时,主要使用的是以下四个代理方法
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
        NSLog(@"接收到响应 --- didReceiveResponse");
}
//可能调用多次,数据分段传输
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
        NSLog(@"接收到服务器返回的数据 --- %zd", data.length);
        [self.resultData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
        NSLog(@"请求失败 --- didFailWithError");
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
        NSLog(@"完成响应之后 --- connectionDidFinishLoading");
    
        //解析服务器返回的数据
        NSLog(@"%@", [[NSString alloc] initWithData:self.resultData encoding:NSUTF8StringEncoding]);
}

在 POST 请求中,也有同步 POST 请求、异步 POST 请求、设置代理请求等方式,使用方法和 GET 请求一致,这里就不一一赘述,仅以异步 POST 请求为例,说明其中的区别与注意点。

发送异步 POST 请求

  1. 确定请求路径(请求参数不能放到路径中)
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];    
  1. 创建可变请求对象(默认为 GET 请求)
NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url];   
  • 修改请求方式为 POST

    requestM.HTTPMethod = @"POST";
    
  • 设置请求体(请求参数放到请求体中)

    requestM.HTTPBody = [@"username=520&pwd=520&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
    
  1. 发送异步请求
  2. 解析服务器返回的数据
[NSURLConnection sendAsynchronousRequest:requestM queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        
        //4.解析服务器返回的数据
        NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}];

拓展

  • 中文乱码转码问题

    • 在以上发送请求的过程中,如果请求路径中存在中文,需要在发送请求之前对中文进行转码,否则会请求失败
    • 在我们日常使用浏览器的时候,浏览器会自动对 URL 进行转码处理
    //如果请求路径中有中文,需要对中文进行转码操作
    NSString *string = @"http://120.25.226.186:32812/login2?username=哈哈哈&pwd=520&type=JSON";
    //转码
    string = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL *url = [NSURL URLWithString:string];
    
  • NSURLConneection 与 Runloop 的联系

    • 设置代理的方法中,如果立即发送请求,那么内部会自动将 connection 作为一个 source 添加到 runloop 中
    • 设置代理的方法中,如果设置为 NO 不立即发送请求,那么内部不会添加 connection 到 runloop 中,需调用 start 方法
    • 如果当前 connection 未被添加到 runloop 中,那么 start 内部会把当前的 connection 添加到 runloop 并设置模式为默认,如果 runloop 不存在,那么会主动创建

关于苹果推荐使用的 NSURLSession 的使用,请来这里:开发只懂 AFN ?搞定 NSURLSession 才是硬道理

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

推荐阅读更多精彩内容

  • iOS开发系列--网络开发 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博、微信等,这些应用本身可...
    lichengjin阅读 3,650评论 2 7
  • 同步请求可以从因特网请求数据, 一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成, 才可以进行下一步操...
    小灬博阅读 877评论 2 4
  • 1.简单请求.url中的多值参数问题 如下代码NSURL *url = [NSURL URLWithString:...
    SoftKnife阅读 506评论 3 2
  • URL URL 全称是Uniform Resource Locator,即统一资源定位符,通过一个URL,可以找到...
    fwlong阅读 2,035评论 0 4
  • 常用类 NSURL:请求地址 NSURLRequest:一个NSURLRequest对象就代表一个请求,它包含的信...
    JonesCxy阅读 975评论 0 1