NSURLSession实现文件下载

前言:非常繁琐,因为要频繁地拼接参数

#import "ViewController.h"

//分隔符,可以随便写(不能有中文和特殊字符)
#define kboundary @"----WebKitFormBoundaryTXB9yxAAArxFVoHf"
#define KNewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]
@interface ViewController ()

@end

@implementation ViewController

/*
 文件上传(拼接文件参数+拼接非文件参数+结尾标识)
 1)设置请求头信息,告诉服务器这是一个文件上传请求,请准备接收我上传的数据
    Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryTXB9yxAAArxFVoHf
 2)POST
 3)上传的文件和非文件参数必须要按照固定的格式来拼接
 
 ------WebKitFormBoundaryTXB9yxAAArxFVoHf
 Content-Disposition: form-data; name="file"; filename="Snip20200808_9.png"
 Content-Type: image/png
 
 
 ------WebKitFormBoundaryTXB9yxAAArxFVoHf
 Content-Disposition: form-data; name="username"
 
 xiaomage
 ------WebKitFormBoundaryTXB9yxAAArxFVoHf--
 */

// 文字描述Request Payload中的内容,方便下面用代码写出来(即5.1,5.2,5.3)
/*
 分隔符:----WebKitFormBoundaryTXB9yxAAArxFVoHf
 1)拼接文件参数
    --分隔符
    Content-Disposition: form-data; name="file"; filename="Snip20200808_9.png"
    Content-Type: image/png
    空行
    文件参数
 2)拼接非文件参数
    --分隔符
    Content-Disposition: form-data; name="username"
    空行
    xiaomage(非文件参数)
 3)结尾标识
  --分隔符--
 */
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self upload];
}

-(void)upload
{
    //1.确定URL
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
    
    //2.创建可变的请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    //3.修改请求方法为POST
    request.HTTPMethod = @"POST";
    
    //4.设置请求头信息,上传请求
    NSString *header = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",kboundary];
    [request setValue:header forHTTPHeaderField:@"Content-Type"];
    
    
    //6.创建会话对象,设置代理
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
    //7.创建Task(dataTask downloadTask uploadTask:dataTask)
    /*
     第一个参数:请求对象
     第二个参数:要上传的数据
     */
    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[self getBody] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
       
        //9.解析服务器返回的响应体信息
        NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
    }];
    
    //8.执行Task
    [uploadTask resume];
}
//注意这个是有返回值类型的方法
-(NSData *)getBody
{
    //5.拼接数据
    NSMutableData *uploadData = [NSMutableData data];
    
    //5.1 拼接文件参数
    /*
     --分隔符
     Content-Disposition: form-data; name="file"; filename="Snip20200808_9.png"
     Content-Type: image/png
     空行
     文件参数
     */
    //stringWithFormat后面一定为6个-
    [uploadData appendData:[[NSString stringWithFormat:@"--%@",kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [uploadData appendData:KNewLine];
    
    //http://120.25.226.186:32812/login?username=123&pwd=123&type=JSON
    //username和pwd以及type是参数的名称
    //ZB|123|JSON参数对应的值
    //file参数名称(是固定的,由当前的服务器规定的)
    //文件参数---值
    //filename:Snip20200808_9.png该文件在服务器上面以什么名称保存
    [uploadData appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"123.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [uploadData appendData:KNewLine];
    [uploadData appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
    [uploadData appendData:KNewLine];
    [uploadData appendData:KNewLine];
    
    //要上传的图片的名字
    UIImage *image = [UIImage imageNamed:@"Snip20200808_12"];
    NSData *imageData = UIImagePNGRepresentation(image);
    [uploadData appendData:imageData];
    [uploadData appendData:KNewLine];
    
    //5.2 拼接非文件参数
    /*
     --分隔符
     Content-Disposition: form-data; name="username"
     空行
     xiaomage(非文件参数)
     */
    [uploadData appendData:[[NSString stringWithFormat:@"--%@",kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [uploadData appendData:KNewLine];
    //username 参数名称
    //xiaomage 值
    [uploadData appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [uploadData appendData:KNewLine];
    [uploadData appendData:KNewLine];
    [uploadData appendData:[@"CoderZb" dataUsingEncoding:NSUTF8StringEncoding]];//多余?多余?多余?
    [uploadData appendData:KNewLine];
    
    //5.3 拼接结尾标识
    // --分隔符--      前面6个-,后面2个-
    [uploadData appendData:[[NSString stringWithFormat:@"--%@--",kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    return uploadData;
}

#pragma mark --------------------
#pragma mark NSURLSessionDataDelegate
//bytesSent 表示本次上传文件数据的大小
//totalBytesSent 已经上传的文件大小
//totalBytesExpectedToSend:文件的总大小
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
    NSLog(@"%f",1.0 * totalBytesSent / totalBytesExpectedToSend);
}
@end

截图

NSURLSession实现文件下载_第1张图片
31-14.gif

你可能感兴趣的:(NSURLSession实现文件下载)