美文网首页
NSURLSession-文件上传

NSURLSession-文件上传

作者: EricLihuifeng | 来源:发表于2018-04-04 11:19 被阅读8次
    文件上传步骤
        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<UITouch *> *)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-文件上传

          本文链接:https://www.haomeiwen.com/subject/cqlkhftx.html