• ios开发网络学习十二:NSURLSession实现文件上传


    #import "ViewController.h"
    //                  ----WebKitFormBoundaryvMI3CAV0sGUtL8tr
    #define Kboundary @"----WebKitFormBoundaryjv0UfA04ED44AhWx"
    
    #define KNewLine [@"
    " dataUsingEncoding:NSUTF8StringEncoding]
    
    @interface ViewController ()<NSURLSessionDataDelegate>
    /** 注释 */
    @property (nonatomic, strong) NSURLSession *session;
    @end
    
    @implementation ViewController
    
    -(NSURLSession *)session
    {
        if (_session == nil) {
            NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
            
            //是否运行蜂窝访问
            config.allowsCellularAccess = YES;
            config.timeoutIntervalForRequest = 15;
            
            _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        }
        return _session;
    }
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        [self upload2];
    }
    
    -(void)upload
    {
        //1.url
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
        
        //2.创建请求对象
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        //2.1 设置请求方法
        request.HTTPMethod = @"POST";
    
        //2.2 设请求头信息
        [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
        
        //3.创建会话对象
    //    NSURLSession *session = [NSURLSession sharedSession];
        
        //4.创建上传TASK
        /*
         第一个参数:请求对象
         第二个参数:传递是要上传的数据(请求体)
         第三个参数:
         */
       NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithRequest:request fromData:[self getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
           
           //6.解析
           NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
        }];
        
        //5.执行Task
        [uploadTask resume];
    }
    
    -(void)upload2
    {
        //1.url
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
        
        //2.创建请求对象
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        //2.1 设置请求方法
        request.HTTPMethod = @"POST";
        
        //2.2 设请求头信息
        [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
        
        //3.创建会话对象
        
        //4.创建上传TASK
        /*
         第一个参数:请求对象
         第二个参数:传递是要上传的数据(请求体)
         */
        NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithRequest:request fromData:[self getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            
            //6.解析
            NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
        }];
        
        //5.执行Task
        [uploadTask resume];
    }
    
    -(NSData *)getBodyData
    {
        NSMutableData *fileData = [NSMutableData data];
        //5.1 文件参数
        /*
         --分隔符
         Content-Disposition: form-data; name="file"; filename="Snip20160225_341.png"
         Content-Type: image/png(MIMEType:大类型/小类型)
         空行
         文件参数
         */
        [fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        
        //name:file 服务器规定的参数
        //filename:Snip20160225_341.png 文件保存到服务器上面的名称
        //Content-Type:文件的类型
        [fileData appendData:[@"Content-Disposition: form-data; name="file"; filename="Sss.png"" dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        [fileData appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        [fileData appendData:KNewLine];
        
        UIImage *image = [UIImage imageNamed:@"Snip20160226_90"];
        //UIImage --->NSData
        NSData *imageData = UIImagePNGRepresentation(image);
        [fileData appendData:imageData];
        [fileData appendData:KNewLine];
        
        //5.2 非文件参数
        /*
         --分隔符
         Content-Disposition: form-data; name="username"
         空行
         123456
         */
        [fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        [fileData appendData:[@"Content-Disposition: form-data; name="username"" dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        [fileData appendData:KNewLine];
        [fileData appendData:[@"123456" dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        
        //5.3 结尾标识
        /*
         --分隔符--
         */
        [fileData appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        return fileData;
    }
    
    #pragma mark ----------------------
    #pragma mark NSURLSessionDataDelegate
    /*
     *  @param bytesSent                本次发送的数据
     *  @param totalBytesSent           上传完成的数据大小
     *  @param 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

    #####7 NSURLSession实现文件上传

    (1)实现文件上传的方法

    ```objc

          /*

         第一个参数:请求对象

         第二个参数:请求体(要上传的文件数据)

         block回调:

         NSData:响应体

         NSURLResponse:响应头

         NSError:请求的错误信息

         */

        NSURLSessionUploadTask *uploadTask =  [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error)

    ```

    (2)设置代理,在代理方法中监听文件上传进度

    ```objc

    /*

     调用该方法上传文件数据

     如果文件数据很大,那么该方法会被调用多次

     参数说明:

         totalBytesSent:已经上传的文件数据的大小

         totalBytesExpectedToSend:文件的总大小

     */

    -(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend

    {

        NSLog(@"%.2f",1.0 * totalBytesSent/totalBytesExpectedToSend);

    }

    ```

    (3)关于NSURLSessionConfiguration相关

        01 作用:可以统一配置NSURLSession,如请求超时等

        02 创建的方式和使用

    ```objc

    //创建配置的三种方式

    + (NSURLSessionConfiguration *)defaultSessionConfiguration;

    + (NSURLSessionConfiguration *)ephemeralSessionConfiguration;

    + (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0);

    //统一配置NSURLSession

    -(NSURLSession *)session

    {

        if (_session == nil) {

            //创建NSURLSessionConfiguration

            NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

            //设置请求超时为10秒钟

            config.timeoutIntervalForRequest = 10;

            //在蜂窝网络情况下是否继续请求(上传或下载)

            config.allowsCellularAccess = NO;

            _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];

        }

        return _session;

    }

    ```

  • 相关阅读:
    spring入门
    mybatis环境配置与入门例子
    wine 魔兽争霸
    不要再使用工具格式化代码!!!
    Android 动画 setVisibility 后出错解决方法
    AbsListView.OnScrollListener 使用注意事项
    linux 配置 wlan 连接
    练习:求完数问题
    重写:求比指定数大且最小的“不重复数”问题
    emacs 快捷键笔记
  • 原文地址:https://www.cnblogs.com/cqb-learner/p/5863237.html
Copyright © 2020-2023  润新知