NSURLSession访问网络数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NSURLSession访问网络数据相关的知识,希望对你有一定的参考价值。

1.NSMutableURLRequest的设置

//创建NSMutableURLRequest对象

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

//设置请求类型

[request setHTTPMethod:@"POST"];

//设置超时时间

[request setTimeoutInterval:60];

//设置缓存策略

[request setCachePolicy:NSURLRequestReloadIgnoringCacheData];

//设置Base64认证

NSString *authString = [[[NSString stringWithFormat:@"%@:%@",kGlobal.userInfo.sAccount,kGlobal.userInfo.sPassword] dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
authString = [NSString stringWithFormat: @"Basic %@", authString];
[request setValue:authString forHTTPHeaderField:@"Authorization"];

//设置POST方法需要传递的参数

NSString *paramStr = [NSString stringWithFormat:@"PostID=%@&Name=%@&Text=%@",self.uuID,kGlobal.userInfo.sApplyName,self.textView.text];
NSData *bodyData = [paramStr dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:bodyData];

2.创建网络会话

//创建网络会话

NSURLSession *session = [NSURLSession sharedSession];

3.创建网络请求(本文介绍 NSURLSessionDataTask 和 NSURLSessionUploadTask 两种)

//方案一:使用NSURLSessionDataTask请求网络数据

NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {
            NSLog(@"文字发布成功!");
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;//将response对象强制转换为NSHTTPURLResponse,可以获取HTTP响应报文的头信息,如响应代码200表示请求成功可以用(httpResponse.statusCode获取)
            NSLog(@"返回的Response:%@",httpResponse);
            NSError *error = nil;
       //而真正的HTTP响应的Body内容则需要序列化获取 NSDictionary
*dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];//返回一个字典类型数据
       //NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];//返回一个JSON数组
//NSArray *array = [NSJSONSerialization JSONObjectWithData:[[dic valueForKey:@"Pictures"] dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error];//
[dic valueForKey:@"Pictures"]得到的是第一次解析得到的JSON Array的字符串,需要二次解析成JSON的数组      
if (!error) {
                NSLog(@"返回信息:%@",dic);
            }
        }else{
            NSLog(@"发布失败,代码%@",error);
        }
}];

4.发送网络请求

[task resume];

 

//方案二:使用NSURLSessionUploadTask请求网络数据,NSURLSessionUploadTask 和 NSURLSessionDataTask的不同之处在于NSURLSessionUploadTask更像Web的表单提交,例如模拟Web表单的图片上传可以使用NSURLSessionUploadTask。

NSURLSessionUploadTask *dataTask = [session uploadTaskWithRequest:request fromData:bodyData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {if (error == nil) {
            NSLog(@"发布成功!");
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
            NSLog(@"statusCode:%lu",httpResponse.statusCode);
            NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
            
            if (picNum == self.imgsArray.count) {
                [SVProgressHUD showSuccessWithStatus:kTXT(@"IMUploadSuccess")];
                [self dismissViewControllerAnimated:YES completion:nil];
            }

        }else{
            NSLog(@"发布失败,代码%@!",error);
        }
}];

上面发送网络请求的方法和方法一的不同之处在于bodyData的构建,方法二的bodyData是模拟HTTP的报文结构来的,使用NSData来拼接HTTP报文。

//bodyData的构建方法

- (NSData *)getBodydataWithImage:(UIImage *)image
{
    //把文件转换为NSData
    NSData *fileData = UIImageJPEGRepresentation(image, 1.0);
    
    NSString *fileName=[Global getUniqueStrByUUID];
    
    //1.构造body string
    NSMutableString *bodyString = [[NSMutableString alloc] init];
    
    //2.拼接body string
    //(1)file_name
    [bodyString appendFormat:@"--%@\\r\\n",boundry];
    [bodyString appendFormat:@"Content-Disposition: form-data; name=\\"FileName\\"\\r\\n"];
    [bodyString appendFormat:@"Content-Type: text/plain; charset=\\"utf-8\\"\\r\\n\\r\\n"];
    [bodyString appendFormat:@"aaa%@.jpg\\r\\n",fileName];
    
    //(2)PostID
    [bodyString appendFormat:@"--%@\\r\\n",boundry];
    [bodyString appendFormat:@"Content-Disposition: form-data; name=\\"PostID\\"\\r\\n"];
    [bodyString appendFormat:@"Content-Type: text/plain; charset=\\"utf-8\\"\\r\\n\\r\\n"];
    [bodyString appendFormat:@"%@\\r\\n",self.uuID];
    
    //(3)pic
    [bodyString appendFormat:@"--%@\\r\\n",boundry];
    [bodyString appendFormat:@"Content-Disposition: form-data; name=\\"pic\\"; filename=\\"%@.jpg\\"\\r\\n",fileName];
    [bodyString appendFormat:@"Content-Type: image/jpeg\\r\\n\\r\\n"];
    //[bodyString appendFormat:@"Content-Type: application/octet-stream\\r\\n\\r\\n"];
    
    //3.string --> data
    NSMutableData *bodyData = [NSMutableData data];
    //拼接的过程
    //前面的bodyString, 其他参数
    [bodyData appendData:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
    //图片数据
    [bodyData appendData:fileData];
    
    //4.结束的分隔线
    NSString *endStr = [NSString stringWithFormat:@"\\r\\n--%@--\\r\\n",boundry];
    //拼接到bodyData最后面
    [bodyData appendData:[endStr dataUsingEncoding:NSUTF8StringEncoding]];
    
    return bodyData;
}

整个bodyData的构建过程原理根据HTTP报文上传图片时,格式用boundory进行分割,但是每次HTTP报文的boundory的值是不一样的,这里为了方便就定义一个固定值,其实固定值也是可以上传成功,亲测有效。HTTP的body体里面把文字和图片内容用boundory和换行符进行分割,分区发送,邮件内容也是类似,所以只要遵循HTTP报文的格式,就可以模拟HTTP报文上传图片。

//boundry的设置

static NSString *boundry = @"----------V2ymHFg03ehbqgZCaKO6jy";//设置边界

//[Global getUniqueStrByUUID]是工具类的方法,用于产生一个GUID,具体的方法明细如下:

+ (NSString *)getUniqueStrByUUID
{
    CFUUIDRef    uuidObj = CFUUIDCreate(nil);//create a new UUID
    
    //get the string representation of the UUID
    
    NSString    *uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(nil, uuidObj);
    
    CFRelease(uuidObj);
    
    return uuidString ;
}

 

实例代码

 

 

 

 

 

 

以上是关于NSURLSession访问网络数据的主要内容,如果未能解决你的问题,请参考以下文章

UI进阶之数据解析(网络请求NSURLSession)

NSURLSession与NSURLConnection区别

如何通过 AFNetworking 和 NSUrlSession 调用 SOAP Web 服务

iOS开发-NSURLSession

iOS学习笔记21-NSUrlSession与NSUrlConnection

基于 NSURLSession 的网络模式