美文网首页
网络编程(08)NSURLSessionUploadTask 上

网络编程(08)NSURLSessionUploadTask 上

作者: Rui哥 | 来源:发表于2018-05-25 13:10 被阅读63次

    一 NSURLSessionUploadTask 上传文件大致步骤:

    #define Kboundary @"----WebKitFormBoundaryATJp9y6FGSNtJKNW"   // 这个是分割符
    
    1> 确定文件上传的路径URL
    2> 创建一个NSMutableRequest  (request)
    3> 设置request 的请求请求方式为 POST
    4> 设置请求头信息Content-Type,告诉服务器这时一个上传文件的请求: 分割符是什么
    [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
    5> 按照固定的格式设置请求体 (请求体包含具体的请求参数 和 要上传的文件数据)
    6> 创建Session
    7> 使用session 创建NSURLSessionUploadTask
    8> 指行task 上传数据
    

    二上传文件请求体详解

    • 概览
    --分隔符
    Content-Disposition: form-data; name="file"; filename="Snip20161126_210.png"
    Content-Type: image/png
    
    需要上传的文件数据
    --分隔符
    Content-Disposition: form-data; name="username"
    
    abc
    --分隔符--
    
    • 上传文件请求体分析,其实可以看出是分为3个部分的
      1> 第一个部分: 文件参数部分
    --分隔符
    Content-Disposition: form-data; name="file"; filename="Snip20161126_210.png"
    Content-Type: image/png
    
    需要上传的文件数据
    

    2> 第二个部分: 非文件参数部分

    --分隔符
    Content-Disposition: form-data; name="username"
    
    abc
    

    3> 第三个部分: 结尾标识

    --分隔符--
    

    三上传文件实现

    • 方式一
    #define Kboundary @"----WebKitFormBoundaryATJp9y6FGSNtJKNW"  //分隔符
    #define KnewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding] // 换行
    
    
    
    -(void)upload1
    {
        //(1)确定上传路径
        NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/upload"];
        
        //(2)创建"可变"请求对象
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        
        //(3)修改请求方法为POST
        request.HTTPMethod = @"POST";
        
        //+ "设置请求头信息,告诉服务器这是一个文件上传请求"
        //Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryATJp9y6FGSNtJKNW
        [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
        
        //+ "按照固定的格式来拼接数据"
        //(4)设置请求体信息(文件参数)
        
        //(5)创建会话对象
        NSURLSession *session = [NSURLSession sharedSession];
        
        //(6)根据会话对象来创建uploadTask
        /* 参数说明
         *
         * 第一个参数:请求对象
         * 第二个参数:本应该放在请求体中的信息
    [self bodyData] 相当于POST请求的 请求体,上传文件时要填写着这个地方,填在 request 的 请求头里是会被忽略的
         */
        NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[self bodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            
            NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
        }];
        
        //(7)执行task发送请求上传文件
        [uploadTask resume];
    
    }
    
    
    
    
    // 上传文件的请求体
    -(NSData *)bodyData
    {
        NSMutableData *data = [NSMutableData data];
        
        //01 拼接文件参数
        /*
        --分隔符
        Content-Disposition: form-data; name="file"; filename="Snip20161126_210.png"
        Content-Type: image/png
        空行
        文件数据
         */
        [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        //name:file 服务器规定
        //filename:该文件上传到服务器之后的名称
        //username|pwd
        [data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"Snip20161126_210.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        //要上传文件的二进制数据类型  MIMEType 组成:大类型/小类型
        [data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        [data appendData:KnewLine];
        NSData *imageData = [NSData dataWithContentsOfFile:@"/Users/xiaomage/Desktop/Snip20161126_238.png"];
        [data appendData:imageData];
        [data appendData:KnewLine];
        
        //02 拼接非文件参数
        /*
         --分隔符
         Content-Disposition: form-data; name="username"
         空行
         abcdf
         */
        [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        //name:username
        [data appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        [data appendData:KnewLine];
        [data appendData:[@"abcdef" dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        
        //03 结尾标识
        /*
         --分隔符--
         */
         [data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        
        return data;
    }
    
    
    
    • 方式二 监听上传进度
    #define Kboundary @"----WebKitFormBoundaryATJp9y6FGSNtJKNW"
    #define KnewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]
    @interface ViewController ()<NSURLSessionDataDelegate>
    
    
    
    
    
    
    -(void)upload2
    {
        //(1)确定上传路径
        NSURL *url = [NSURL URLWithString:@"http://http://127.0.0.1/upload/upload"];
        
        //(2)创建"可变"请求对象
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        
        //(3)修改请求方法为POST
        request.HTTPMethod = @"POST";
        
        //+ "设置请求头信息,告诉服务器这是一个文件上传请求"
        //Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryATJp9y6FGSNtJKNW
        [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
        
        //+ "按照固定的格式来拼接数据"
        //(4)设置请求体信息(文件参数)
        
        //(5)创建会话对象 设置代理 以便监听上传的进度
       NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
                                                              delegate:self
                                                         delegateQueue:[NSOperationQueue mainQueue]];
        
        //(6)根据会话对象来创建uploadTask
        /* 参数说明
         *
         * 第一个参数:请求对象
         * 第二个参数:本应该放在请求体中的信息
         */
        NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[self bodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            
            NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
        }];
        
        //(7)执行task发送请求上传文件
        [uploadTask resume];
        
    }
    
    
    
    
    
    
    -(NSData *)bodyData
    {
        NSMutableData *data = [NSMutableData data];
        
        //01 拼接文件参数
        /*
        --分隔符
        Content-Disposition: form-data; name="file"; filename="Snip20161126_210.png"
        Content-Type: image/png
        空行
        文件数据
         */
        [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        //name:file 服务器规定
        //filename:该文件上传到服务器之后的名称
        //username|pwd
        [data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"Snip20161126_210.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        //要上传文件的二进制数据类型  MIMEType 组成:大类型/小类型
        [data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        [data appendData:KnewLine];
        NSData *imageData = [NSData dataWithContentsOfFile:@"/Users/xiaomage/Desktop/Snip20161126_238.png"];
        [data appendData:imageData];
        [data appendData:KnewLine];
        
        //02 拼接非文件参数
        /*
         --分隔符
         Content-Disposition: form-data; name="username"
         空行
         abcdf
         */
        [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        //name:username
        [data appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        [data appendData:KnewLine];
        [data appendData:[@"abcdef" dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:KnewLine];
        
        //03 结尾标识
        /*
         --分隔符--
         */
         [data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        
        return data;
    }
    
    
    
    #pragma mark NSURLSessionDataDelegate 
    -(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);
    }
    
    
    
    
    

    相关文章

      网友评论

          本文标题:网络编程(08)NSURLSessionUploadTask 上

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