NSURLSession-文件上传

文件上传步骤
    1、确定文件上传路径
    2、创建可变的请求对象
    3、修改请求的方式为POST
       + 需要设置请求头信息 告诉服务器这是一个文件上传请求
    4、设置请求体信息 (文件参数)
    5、创建会话对象
    6、根据会话对象创建uploadTask
    7、执行tast 上传文件

特殊之处

 (1) 设置请求头信息
    Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryKdulihuifeng123

(2) 按照固定格式拼接数据   (文件参数的拼接格式)
    ------WebKitFormBoundaryKdulihuifeng123
    Content-Disposition: form-data; name="file"; filename="123.png"
    Content-Type: image/png


    ------WebKitFormBoundaryKdulihuifeng123
    Content-Disposition: form-data; name="username"

    abc123
    ------WebKitFormBoundaryKdulihuifeng123--

简化

分隔符:----WebKitFormBoundaryKdulihuifeng123
文件参数
    --分隔符
    Content-Disposition:参数
    Content-Type:参数
    空行
    文件数据
非文件参数
    --分隔符
    Content-Disposition:参数
    空行
    abc123 (非文件的二进制数据)
结尾标识
    --分隔符--

代码

1.NSURLSessionUploadTask-block 上传文件

#define Kboundary @"----WebKitFormBoundaryKdulihuifeng123"
#define KNewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    //1、确定文件上传路径
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
    
    //2、创建可变的请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    //3、修改请求的方式为POST
    request.HTTPMethod = @"POST";
    
    //+ 需要设置请求头信息 告诉服务器这是一个文件上传请求
    NSString *header = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
    [request setValue:header forHTTPHeaderField:@"Content-Type"];
    //4、设置请求体信息 (文件参数)
    //5、创建会话对象
    NSURLSession *session = [NSURLSession sharedSession];

    //6、根据会话对象创建uploadTask
    // session上传不需要设置请求体,如果数据在request中会被忽略。
    /* 参数说明
     * 第一个参数 请求对象
     * 第二个参数 本应该放在请求体中的信息
     */
    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[self getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
    }];
    
    //7、执行tast 上传文件
    [uploadTask resume];
}

-(NSData *)getBodyData
{
    //4.设置请求体
    NSMutableData *data = [NSMutableData data];
    //4.1 文件参数
    /*
     --分隔符
     Content-Disposition: form-data; name="file"; filename="123.png"
     Content-Type: image/png
     空行
     文件数据
     */
    
 [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    //name:file  服务器规定的 file不能变固定的
    //filename="123.png" 该文件上传到服务器之后的名称 可以按自己的需求来写 没什么限制
    
    [data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"123.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    //要上传的文件的二进制数据类型 MIMEType 组成:大类型/小类型  image是大类型 png是小类型
    [data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    [data appendData:KNewLine];
    
    UIImage *image = [UIImage imageNamed:@"123"];
    NSData *imageData = UIImagePNGRepresentation(image);
    [data appendData:imageData];
    [data appendData:KNewLine];
   
    //4.2 非文件参数
    /*
     --分隔符
     Content-Disposition: form-data; name="username"
     空行
     abc123
     */
    [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    [data appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    [data appendData:KNewLine];
    [data appendData:[@"abc123" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    
    //4.3 结尾标识
    /*
     --分隔符--
     */
    [data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    return data;
}

2.NSURLSessionUploadTask-代理方式 上传文件 (可以监听进度)

- (void)uploadDelegate{
    //1、确定文件上传路径
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
    
    //2、创建可变的请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    //3、修改请求的方式为POST
    request.HTTPMethod = @"POST";
    
    //+ 需要设置请求头信息 告诉服务器这是一个文件上传请求
    NSString *header = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
    [request setValue:header forHTTPHeaderField:@"Content-Type"];
    //4、设置请求体信息 (文件参数)
    //5、创建会话对象
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
    //6、根据会话对象创建uploadTask
    // session上传不需要设置请求体,如果数据在request中会被忽略。
    /* 参数说明
     * 第一个参数 请求对象
     * 第二个参数 本应该放在请求体中的信息
     */
    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[self getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
    }];
    
    //7、执行tast 上传文件
    [uploadTask resume];
}

-(NSData *)getBodyData
{
    //4.设置请求体
    NSMutableData *data = [NSMutableData data];
    //4.1 文件参数
    /*
     --分隔符
     Content-Disposition: form-data; name="file"; filename="123.png"
     Content-Type: image/png
     空行
     文件数据
     */
    
    [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    //name:file  服务器规定的 file不能变固定的
    //filename="123.png" 该文件上传到服务器之后的名称 可以按自己的需求来写 没什么限制
    
    [data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"123.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    //要上传的文件的二进制数据类型 MIMEType 组成:大类型/小类型  image是大类型 png是小类型
    [data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    [data appendData:KNewLine];
    
//    UIImage *image = [UIImage imageNamed:@"123"];
//    NSData *imageData = UIImagePNGRepresentation(image);
    NSData *imageData = [NSData dataWithContentsOfFile:@"/Users/a58/Desktop/123.png"];
    [data appendData:imageData];
    [data appendData:KNewLine];
   
    //4.2 非文件参数
    /*
     --分隔符
     Content-Disposition: form-data; name="username"
     空行
     abc123
     */
    [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    [data appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    [data appendData:KNewLine];
    [data appendData:[@"abc123" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    
    //4.3 结尾标识
    /*
     --分隔符--
     */
    [data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KNewLine];
    return data;
}


#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);
}

监听进度log

2018-04-04 16:18:30.125851+0800 NSURLSession文件上传[1870:155810] 上传进度-- 0.635642
2018-04-04 16:18:30.126051+0800 NSURLSession文件上传[1870:155810] 上传进度-- 1.000000
2018-04-04 16:18:30.339630+0800 NSURLSession文件上传[1870:155810] {"success":"上传成功"}

你可能感兴趣的:(NSURLSession-文件上传)