iOS网络请求

iOS网络请求

本文讲解了用iOS原生套类URLSession实现网络请求的方式方法。
本文阅读大概需要10分钟左右

HTTP协议

网络数据通信需要遵守数据传输协议,几乎所有的客户端服务器网络通信都是基于HTTP协议的。关于HTTP协议妹子就不废话了,网上没有10000也有5000篇这种文章的介绍,这里推荐一篇速览文章,短小易懂快速理解HTTP协议

URLSession

做iOS开发的肯定都知道URLSession,但是大家天天用网络框架估计都对URLSession有点模糊了,妹子这里用URLSession写两个请求,帮大家复习下这个套类是怎样做GET&POST请求的,另外关URLSession的文章详解的文章有很多,可以去详细了解下。

GET请求

妹子在这里申请了一个聚合数据的账号做测试用,请求的常用快递查询接口,大家如果想做测试可以去自己申请一个

//配置config选项
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.timeoutIntervalForRequest = 30.f; //设置session请求超时30s
//使用config初始化一个 URLSession对象
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
//常用快递查询 GET请求
/**
 参数:
 key:申请的聚合数据的key
 com:快递缩写
 no:快递单号
 type:返回数据格式
 */
NSURL *url = [NSURL URLWithString:@"https://v.juhe.cn/exp/index?key=7ea4e3ec1f227104b8f35ed50bcd6797&com=yt&no=802616352006034501&dtype=json"];
//这里妹子用了session生成datatask任务的获取返回数据的方式callback方式,
//当然以可以使用代理方式的API接口获取数据,下面的POST请求会使用代理方式来获取数据
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    //请求相应的rawData数据,是NSData的二进制数据
    NSLog(@"\ndata=%@\n",data);
    //需要自己做json解析,解析成OC数据结构
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers | NSJSONReadingAllowFragments error:nil];
    NSLog(@"response content dic=%@\n",dic);
    //HTTP相应数据
    NSLog(@"response=%@\n",response);
    //请求发生错误时候返回的数据
    NSLog(@"error=%@",error);
}];
//开启datatask任务
[dataTask resume];

下面是Response的content内容

response content dic={
"error_code" = 0;
reason = "\U67e5\U8be2\U6210\U529f";
result =     {
    com = yt;
    company = "\U5706\U901a";
    list =         (
                    {
            datetime = "2018-11-12 11:51:34";
            remark = "\U5e7f\U4e1c\U7701\U5e7f\U5dde\U5e02\U9ec4\U57d4\U533a\U4e1c\U533a\U6c38\U548c\U516c\U53f8\U53d6\U4ef6\U4eba: \U9ec4\U4f1f\U94a6\Uff0813602438384\Uff09 \U5df2\U6536\U4ef6";
            zone = "";
        },
                    {
            datetime = "2018-11-12 15:30:17";
            remark = "\U5feb\U4ef6\U5df2\U53d1\U5f80 \U5e7f\U5dde\U8f6c\U8fd0\U4e2d\U5fc3";
            zone = "";
        },
                    {
            datetime = "2018-11-12 22:33:51";
            remark = "\U5feb\U4ef6\U5df2\U5230\U8fbe \U5e7f\U5dde\U8f6c\U8fd0\U4e2d\U5fc3";
            zone = "";
        },
                    {
            datetime = "2018-11-12 23:40:29";
            remark = "\U5feb\U4ef6\U5df2\U53d1\U5f80 \U5317\U4eac\U8f6c\U8fd0\U4e2d\U5fc3";
            zone = "";
        },
                    {
            datetime = "2018-11-14 19:09:38";
            remark = "\U5feb\U4ef6\U5df2\U5230\U8fbe \U5317\U4eac\U8f6c\U8fd0\U4e2d\U5fc3";
            zone = "";
        },
                    {
            datetime = "2018-11-15 09:04:03";
            remark = "\U5feb\U4ef6\U5df2\U53d1\U5f80 \U5317\U4eac\U5e02\U671d\U9633\U533a\U89c2\U6e56\U516c\U53f8";
            zone = "";
        }
    );
    no = 802616352006034501;
    status = 0;
};
resultcode = 200;
}

下面是HTTP Response 的返回头以及状态码内容,封装的是HTTP协议中规定的返回响应的内容

{ URL: https://v.juhe.cn/exp/index?key=7ea4e3ec1f227104b8f35ed50bcd6797&com=yt&no=802616352006034501&dtype=json } { Status Code: 200, Headers {
Connection =     (
    "keep-alive"
);
"Content-Type" =     (
    "application/json;charset=utf-8"
);
Date =     (
    "Thu, 15 Nov 2018 03:07:01 GMT"
);
Etag =     (
    02132b8fec79c49b795f7726ed238b59
);
"Set-Cookie" =     (
    "aliyungf_tc=AQAAAOfGX3hMNgAAy0VuJIr54XXOX7Kn; Path=/; HttpOnly"
);
"Transfer-Encoding" =     (
    Identity
);
} }

POST请求

妹子下面演示下用POST请求请求同一个接口

//构造POST请求需要使用NSMutableURLRequest 来封装HTTP Method方法,body请求体
NSMutableURLRequest *request  = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:@"https://v.juhe.cn/exp/index"]];
//设置请求方式POST,妹子这里猜测默认的请求方式应该是GET不然上面的GET方法也不可能请求成功
request.HTTPMethod = @"POST";
//设置请求头部内容,只设置请求content数据格式,其他请求头部内容使用默认的
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
//构造POST请求体 参数还是上面那几个参数 body是二进制NSData类型
//构造参数
/**!!!
 NSString *param = @{@"key" : @"7ea4e3ec1f227104b8f35ed50bcd6797",
 @"com" : @"yt",
 @"no"  : @"802616352006034501",
 @"dtype" : @"json"
 };
 NSData *paramData = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:nil];
 妹子在这里试过类似于dicjson序列化为NSData的方式但是好像这样行不通请求参数错误
      后来调研http请求POST请求的请求体也是用字符串拼接,参数之间用&分开的方式
 **/
NSString *paramStr = @"key=7ea4e3ec1f227104b8f35ed50bcd6797&com=yt&no=802616352006034501&dtype=json";
//使用utf-8编码
NSData *paramData = [paramStr dataUsingEncoding:NSUTF8StringEncoding];
//设置http body
[request setHTTPBody:paramData];
//这里使用URLSession 的代理回调处理请求的响应
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.timeoutIntervalForRequest = 30.f;
//设置session的代理方法 代理方法在哪个线程里面处理
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//创建task
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
//执行task
[dataTask resume];

回调的代理方法在 NSURLSessionDataDelegate 协力里面

#pragma mark - NSURLSessionDataDelegate

//step1.接受到服务器相应 该方法会先被调用
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
 completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler{
NSLog(@"response = %@\n",response);

/**
    判定该次任务是否继续执行,或者转化为其他类型的任务
typedef NS_ENUM(NSInteger, NSURLSessionResponseDisposition) {
    NSURLSessionResponseCancel = 0,         //取消本次task任务
    NSURLSessionResponseAllow = 1,          //本次task任务继续
    NSURLSessionResponseBecomeDownload = 2, //转变本次dataTask任务为一个downloadTask下载任务
    NSURLSessionResponseBecomeStream        //转变本次dataTask任务为一个StreamTask流任务
} NS_ENUM_AVAILABLE(NSURLSESSION_AVAILABLE, 7_0);
 */

//允许本次task继续执行
completionHandler(NSURLSessionResponseAllow);

}

//setp2.数据传输的过程中该方法会被调用 如果返回数据特别长,该方法会被多次调用
// @property(nonatomic,strong)NSMutableData *receiveData; 在上面事先声明好NSMutableData数据拼接返回的data数据
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
    didReceiveData:(NSData *)data{
    NSLog(@"ReceiveData = %@\n", data);
    //拼接返回的数据
    [self.receiveData appendData:data];
}

//step3:数据传输完成最后该方法会被调用 不管最后该次请求成功或者失败该方法都会调用
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    if(error){
    // 请求失败
        NSLog(@"error = %@\n",error);
    }else{
    // 请求成功
        //解析返回的数据
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:self.receiveData options:NSJSONReadingMutableContainers | NSJSONReadingAllowFragments error:nil];
        NSLog(@"response content = %@",dic);
    }
}

总结

客户端的业务80%都是GET POST请求,下一篇妹子会仔细分析下AFNetworking这个协议框架,因为貌似绝大多数项目都用这个框架,这一篇算做了一个铺垫吧。

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

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_x阅读 15,967评论 3 119
  • 文/雪诺 微信公众号:迷茫人生路 我有鸡汤,你有酒吗? 很多时候,往往都是事情改变了我们,我们却改变...
    Snow凤阅读 351评论 0 0
  • 中午放学妈妈接我回家,我回头看了一下操场周围有好多红色的叶子,我问妈妈那是什么?妈妈说不知道啊!要不咱俩去寻找秋天...
    李明翰妈妈阅读 268评论 0 3
  • 1.把家里不用穿的鞋子洗干净晾干,皮鞋上油刷好。 2.用干净的塑料袋包起来,在里面放上干燥剂。 3、用平时买鞋留下...
    兔兔马阅读 551评论 0 0
  • 今天看订阅号推送“优秀的人,都对自己下狠手”,没敢点进去,准确说是没有点开的欲望。即使我想成为优秀的人,我也只想善...
    姗姗莱兹阅读 241评论 1 4