iOS网络编程-URLSession

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这个协议框架,因为貌似绝大多数项目都用这个框架,这一篇算做了一个铺垫吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值