网络请求NSURLSession的使用

准备工作:搭建服务器,后台写好逻辑代码

一、本人用Eclipse+apache搭建的服务器,后台只是写了简单的登录界面,如果密码和用户名都正确就返回登录成功,否则返回登录失败。

二、对url的分析
http://localhost:8080/MJServer/login?username=%@&pwd=%@
http为协议头
localhost:8080 为主机地址,localhost是本机地址,如果是网络的主机地址就填网络主机地址
MJServer/login为接口,后面是参数,在数据库中也是关键字段

三、NSRULSession的使用步骤

1.创建URL(必须)

 NSURL *url = [NSURL URLWithString:urlString];

2.创建请求对象,设置请求对象(不是必须)

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    //设置请求对象的超时时间为4s
    request.timeoutInterval = 4;

3.创建NSURLSessionConfiguration,并且设置(不是必须)

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    //超时时间
    config.timeoutIntervalForRequest = 5;

4.创建NSURLSession(必须)

    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];

5.创建任务(必须)

    //这种方法可以处理文件操作等大型数据
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
//这种方法处理一些轻量数据
//    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}

6.启动任务(必须)

    [task resume];

四、NSURLSession中使用Get方式请求
默认就是Get方式。

/**Get方式*/
-(void)loginOnClickByGetMethod
{
    NSString *username = self.textFieldOne.text;
    NSString *password = self.textFieldTwo.text;
    if (username.length == 0 || password.length == 0) {
        [MBProgressHUD showError:@"请输入账号或密码"];
        return;
    }
    NSString *urlString = [NSString stringWithFormat:@"http://localhost:8080/MJServer/login?username=%@&pwd=%@",username,password];
    //对url进行转码(url不允许有中文)
    urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL *url = [NSURL URLWithString:urlString];

    [MBProgressHUD showMessage:@"拼命加载中"];
    //创建请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    //设置请求对象的超时时间为4s
    request.timeoutInterval = 4;

    [self setupURLSession:request];
   }


   -(void)setupURLSession:(NSURLRequest *)request
{
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    //超时时间
    config.timeoutIntervalForRequest = 5;

    //创建session
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];

 //这种方法处理一些轻量数据
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        //隐藏HUD(刷新UI界面,一定要放在主现场,不能放在子线程)
        [MBProgressHUD hideHUD];
        if(data)//data有值才返回JSON数据,否则JSON为nil程序会崩
            //请求成功
        {
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];

            NSLog(@"dict = %@",dict);
            NSString *error = dict[@"error"];
            if (error) {
                [MBProgressHUD showError:error];
            }
            else
            {
                NSString *success = dict[@"success"];
                [MBProgressHUD showSuccess:success];
            }
        }
        else//请求失败
        {
            [MBProgressHUD showError:@"网络繁忙,请稍后再试"];
        }
    }];

    //启动任务
    [task resume];
}

五、NSURLSession中使用Post方式请求

/**Post方式*/
-(void)loginOnClickByPostMethod
{
    NSString *username = self.textFieldOne.text;
    NSString *password = self.textFieldTwo.text;
    if (username.length == 0 || password.length == 0) {
        [MBProgressHUD showError:@"请输入账号或密码"];
        return;
    }

    NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login"];

    [MBProgressHUD showMessage:@"拼命加载中"];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.timeoutInterval = 4;
    request.HTTPMethod = @"POST";
    //设置请求头告诉服务器客户端的类型
//    [request setValue:@"android-ios" forHTTPHeaderField:@"User-Agent"];

    //设置请求体
    NSString *param = [NSString stringWithFormat:@"username=%@pwd=%@",username,password];
    //转码
    request.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding];

    [self setupURLSession:request];
}


-(void)setupURLSession:(NSURLRequest *)request
{
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    //超时时间
    config.timeoutIntervalForRequest = 5;

    //创建session
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    //这种方法可以处理文件操作等大型数据
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request];    
    //启动任务
    [task resume];
}

因为NSURLSessionDataTask用的是以上的方式,不是block的方式,所以要配合NSURLSessionDataDelegate一起用。首先要遵守NSURLSessionDataDelegate协议,然后就是写上代理方法。

#pragma mark - NSURLSessionDataDelegate
//接收到服务器相应的时候调用该方法
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    //注意:需要使用completionHandler回调告诉系统应该如何处理服务器返回的数据
    //默认是取消的
        /*
                     NSURLSessionResponseCancel = 0,        默认的处理方式,取消
                     NSURLSessionResponseAllow = 1,         接收服务器返回的数据
                     NSURLSessionResponseBecomeDownload = 2,变成一个下载请求
                     NSURLSessionResponseBecomeStream        变成一个流
                  */

    NSLog(@"didReceiveResponse----%@--%@",[NSThread currentThread],dataTask);
    completionHandler(NSURLSessionResponseAllow);
}

//接收到服务器返回的数据就会调用该方法,如果数据较大的话该方法可能会调用多次
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
    NSLog(@"didReceiveData----%@",[NSThread currentThread]);
    [self.responsedata appendData:data];

    NSLog(@"self.responsedata = %@",[NSJSONSerialization JSONObjectWithData:self.responsedata options:NSJSONReadingMutableLeaves error:nil]);

}

//当请求完成时候调用该方法,如果请求失败,则有error值
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    NSLog(@"didCompleteWithError----%@",[NSThread currentThread]);

    [MBProgressHUD hideHUD];
    //请求成功
    {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.responsedata options:NSJSONReadingMutableLeaves error:nil];

        NSLog(@"dict = %@",dict);
        NSString *error = dict[@"error"];
        if (error) {
            [MBProgressHUD showError:error];
        }
        else
        {
            NSString *success = dict[@"success"];
            [MBProgressHUD showSuccess:success];
        }
    }
}

六、由于服务器返回的是JSON格式的数据,由于编码原因,中文会打印乱码。此时,我们用一个创建一个分类,继承NSDictionary的分类,实现方法如下:

@implementation NSDictionary (JsonLog)

-(NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
    //初始化可变字符串
    NSMutableString *string = [NSMutableString string];
    //拼接开头[
    [string appendString:@"["];

    //拼接字典中所有的键值对
    [self enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        [string appendFormat:@"%@:",key];
        [string appendFormat:@"%@",obj];
    }];

    //拼接结尾]
    [string appendString:@"]"];

    return string;
}

@end

这样就能直接打印出来中文,方便数据的测试。

测试数据:

2017-04-26 17:40:17.738 NSURLSession[3068:286241] didReceiveResponse----<NSThread: 0x600000077d40>{number = 1, name = main}--<__NSCFLocalDataTask: 0x7f88a5431320>{ taskIdentifier: 1 } { suspended }
2017-04-26 17:40:17.738 NSURLSession[3068:286241] didReceiveData----<NSThread: 0x600000077d40>{number = 1, name = main}
2017-04-26 17:40:17.739 NSURLSession[3068:286241] self.responsedata = [success:登录成功]
2017-04-26 17:40:17.739 NSURLSession[3068:286241] didCompleteWithError----<NSThread: 0x600000077d40>{number = 1, name = main}
2017-04-26 17:40:17.739 NSURLSession[3068:286241] dict = [success:登录成功]

网络请求NSURLSession的使用_第1张图片

网络请求NSURLSession的使用_第2张图片

你可能感兴趣的:(iOS-系统类的详解)