zoukankan      html  css  js  c++  java
  • iOS开发AFN使用二:AFN文件下载与文件上传

    #import "ViewController.h"
    #import "AFNetworking.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        [self download];
    }
    
    -(void)download
    {
        //1.创建会话管理者
        AFHTTPSessionManager *manager =[AFHTTPSessionManager manager];
        
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
        
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        
        //2.下载文件
        /*
         第一个参数:请求对象
         第二个参数:progress 进度回调 downloadProgress
         第三个参数:destination 回调(目标位置)
                    有返回值
                    targetPath:临时文件路径
                    response:响应头信息
         第四个参数:completionHandler 下载完成之后的回调
                    filePath:最终的文件路径
         */
        
        /*
         第一个参数:请求对象
         第二个参数:进度回调
         downloadProgress.completedUnitCount :已经下载的数据
         downloadProgress.totalUnitCount:数据的总大小
         第三个参数:destination回调,该block需要返回值(NSURL类型),告诉系统应该把文件剪切到什么地方
         targetPath:文件的临时保存路径tmp,随时可能被删除
         response:响应头信息
         第四个参数:completionHandler请求完成后回调
         response:响应头信息
         filePath:文件的保存路径,即destination回调的返回值
         error:错误信息
         */
        NSURLSessionDownloadTask *download = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
            
            //监听下载进度
            //completedUnitCount 已经下载的数据大小
            //totalUnitCount     文件数据的中大小
            NSLog(@"%f",1.0 *downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
            
        } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
            /**
             * 1:1:请求路径:NSUrl *url = [NSUrl urlWithString:path];从网络请求路径  2:把本地的file文件路径转成url,NSUrl *url = [NSURL fileURLWithPath:fullPath];
               2:返回值是一个下载文件的路径
             *
             */
            NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
            
            NSLog(@"targetPath:%@",targetPath);
            NSLog(@"fullPath:%@",fullPath);
            
            return [NSURL fileURLWithPath:fullPath];
        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
            /**
             *filePath:下载后文件的保存路径
             */
            NSLog(@"%@",filePath);
        }];
        
        //3.执行Task
        [download resume];
    }
    
    
    @end

    (2)使用AFN下载文件

    ```objc

    -(void)download

    {

        //1.创建会话管理者

        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

        //2.创建请求对象

        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_13.png"]];

        //3.创建下载Task

        /*

         第一个参数:请求对象

         第二个参数:进度回调

            downloadProgress.completedUnitCount :已经下载的数据

            downloadProgress.totalUnitCount:数据的总大小

         第三个参数:destination回调,该block需要返回值(NSURL类型),告诉系统应该把文件剪切到什么地方

            targetPath:文件的临时保存路径

            response:响应头信息

         第四个参数:completionHandler请求完成后回调

            response:响应头信息

            filePath:文件的保存路径,即destination回调的返回值

            error:错误信息

         */

        NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {

            NSLog(@"%f",1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);

        } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {

            NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];

            NSLog(@"%@ %@",targetPath,fullPath);

            return [NSURL fileURLWithPath:fullPath];

        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {

            NSLog(@"%@",filePath);

        }];

        //4.执行Task

        [downloadTask resume];

    }

    ```

     二:文件上传

    #import "ViewController.h"
    #import "AFNetworking.h"
    
    
    #define Kboundary @"----WebKitFormBoundaryjv0UfA04ED44AhWx"
    
    #define KNewLine [@"
    " dataUsingEncoding:NSUTF8StringEncoding]
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        [self upload2];
    }
    
    //不推荐
    -(void)upload
    {
        //1.创建会话管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
        //2.1url
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
        
        //2.2创建请求对象
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        //2.3 设置请求方法
        request.HTTPMethod = @"POST";
        
        //2.4 设请求头信息
        [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
        
        //3.发送请求上传文件
        NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromData:[self getBodyData] progress:^(NSProgress * _Nonnull uploadProgress) {
            NSLog(@"%f",1.0 * uploadProgress.completedUnitCount/ uploadProgress.totalUnitCount);
            
        } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
           
            NSLog(@"%@",responseObject);
        }];
        
        //4.执行task
        [uploadTask resume];
    }
    
    -(void)upload2
    {
        //1.创建会话管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
    //    NSDictionary *dictM = @{}
        //2.发送post请求上传文件
        /*
         第一个参数:请求路径
         第二个参数:字典(非文件参数)
         第三个参数:constructingBodyWithBlock 处理要上传的文件数据
         第四个参数:进度回调
         第五个参数:成功回调 responseObject:响应体信息
         第六个参数:失败回调
         */
        [manager POST:@"http://120.25.226.186:32812/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            
            /**
             *    1:将image转换成NSData:可用 UIImagePNGRepresentation,也可用UIImageJPEGRepresentation
                2:data转换成image:UIImage *image = [UIImage imageWithData:data];
                3:url:1;网络路径:NSUrl urlWithString 2:NSUrl fileUrlWithStr:本地文件路径
                4:第三种方法:没有传fileName 和 mimeType,由AFN内部去自动设置,fileName截取的文件的url路径,mimeType由c语言内部去获取
             */
            UIImage *image = [UIImage imageNamed:@"Snip20160227_128"];
            NSData *imageData = UIImagePNGRepresentation(image);
            
            //使用formData来拼接数据
            /*
             第一个参数:二进制数据 要上传的文件参数
             第二个参数:服务器规定的
             第三个参数:该文件上传到服务器以什么名称保存
             */
            //[formData appendPartWithFileData:imageData name:@"file" fileName:@"xxxx.png" mimeType:@"image/png"];
            
            //[formData appendPartWithFileURL:[NSURL fileURLWithPath:@"/Users/xiaomage/Desktop/Snip20160227_128.png"] name:@"file" fileName:@"123.png" mimeType:@"image/png" error:nil];
            
            [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"/Users/xiaomage/Desktop/Snip20160227_128.png"] name:@"file" error:nil];
            
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            
            NSLog(@"%f",1.0 * uploadProgress.completedUnitCount/uploadProgress.totalUnitCount);
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"上传成功---%@",responseObject);
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"上传失败---%@",error);
        }];
        
    }
    -(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:@"Snip20160227_128"];
        //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;
    }
    
    @end

    ###2.AFN文件上传

    ```objc

    1.文件上传拼接数据的第一种方式

    [formData appendPartWithFileData:data name:@"file" fileName:@"xxoo.png" mimeType:@"application/octet-stream"];

    2.文件上传拼接数据的第二种方式

     [formData appendPartWithFileURL:fileUrl name:@"file" fileName:@"xx.png" mimeType:@"application/octet-stream" error:nil];

    3.文件上传拼接数据的第三种方式

     [formData appendPartWithFileURL:fileUrl name:@"file" error:nil];

    4.【注】在资料中已经提供了一个用于文件上传的分类。

    /*文件上传相关的代码如下*/

    -(void)upload1

    {

        //1.创建会话管理者

        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

        //2.处理参数(非文件参数)

        NSDictionary *dict = @{

                               @"username":@"123"

                               };

        //3.发送请求上传文件

        /*

         第一个参数:请求路径(NSString类型)

         第二个参数:非文件参数,以字典的方式传递

         第三个参数:constructingBodyWithBlock 在该回调中拼接文件参数

         第四个参数:progress 进度回调

            uploadProgress.completedUnitCount:已经上传的数据大小

            uploadProgress.totalUnitCount:数据的总大小

         第五个参数:success 请求成功的回调

            task:上传Task

            responseObject:服务器返回的响应体信息(已经以JSON的方式转换为OC对象)

         第六个参数:failure 请求失败的回调

            task:上传Task

            error:错误信息

         */

        [manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {

            UIImage *image = [UIImage imageNamed:@"Snip20160117_1"];

            NSData *imageData = UIImagePNGRepresentation(image);

            //在该block中拼接要上传的文件参数

            /*

             第一个参数:要上传的文件二进制数据

             第二个参数:文件参数对应的参数名称,此处为file是该台服务器规定的(通常会在接口文档中提供)

             第三个参数:该文件上传到服务后以什么名称保存

             第四个参数:该文件的MIMeType类型

             */

            [formData appendPartWithFileData:imageData name:@"file" fileName:@"123.png" mimeType:@"image/png"];

        } progress:^(NSProgress * _Nonnull uploadProgress) {

            NSLog(@"%f",1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);

        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

            NSLog(@"请求成功----%@",responseObject);

        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

            NSLog(@"请求失败----%@",error);

        }];

    }

    -(void)upload2

    {

        //1.创建会话管理者

        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

        //2.处理参数(非文件参数)

        NSDictionary *dict = @{

                               @"username":@"123"

                               };

        //3.发送请求上传文件

        /*

         第一个参数:请求路径(NSString类型)

         第二个参数:非文件参数,以字典的方式传递

         第三个参数:constructingBodyWithBlock 在该回调中拼接文件参数

         第四个参数:progress 进度回调

            uploadProgress.completedUnitCount:已经上传的数据大小

            uploadProgress.totalUnitCount:数据的总大小

         第五个参数:success 请求成功的回调

            task:上传Task

            responseObject:服务器返回的响应体信息(已经以JSON的方式转换为OC对象)

         第六个参数:failure 请求失败的回调

            task:上传Task

            error:错误信息

         */

        [manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {

            NSURL *fileUrl = [NSURL fileURLWithPath:@"/Users/文顶顶/Desktop/Snip20160117_1.png"];

            //在该block中拼接要上传的文件参数

            //第一种拼接方法

            /*

             第一个参数:要上传的文件的URL路径

             第二个参数:文件参数对应的参数名称,此处为file是该台服务器规定的(通常会在接口文档中提供)

             第三个参数:该文件上传到服务后以什么名称保存

             第四个参数:该文件的MIMeType类型

             第五个参数:错误信息,传地址

             */

            //[formData appendPartWithFileURL:fileUrl name:@"file" fileName:@"1234.png" mimeType:@"image/png" error:nil];

            //第二种拼接方法:简写方法

            /*

             第一个参数:要上传的文件的URL路径

             第二个参数:文件参数对应的参数名称,此处为file

             第三个参数:错误信息

             说明:AFN内部自动获得路径URL地址的最后一个节点作为文件的名称,内部调用C语言的API获得文件的类型

             */

            [formData appendPartWithFileURL:fileUrl name:@"file" error:nil];

        } progress:^(NSProgress * _Nonnull uploadProgress) {

            NSLog(@"%f",1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);

        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

            NSLog(@"请求成功----%@",responseObject);

        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

            NSLog(@"请求失败----%@",error);

        }];

    }

    ```

  • 相关阅读:
    win10 + Debian9.1双系统安装笔记
    高效查看MySQL帮助文档的方法 (转)
    初涉Delphi Socket编程
    Delphi xe5 StyleBook的用法(待续)
    Delphi xe5如何使用Bluestacks模拟器(用真机或者用猩猩,夜神模拟器,自带的不好用)
    Delphi xe5 控件TIdhttp的用法post,get解决中文乱码问题
    如何解析DELPHI XE5服务器返回的JSON数据(翻译)及中文乱码
    解决tomcat占用8080端口
    逆地址解析协议
    前后端分离
  • 原文地址:https://www.cnblogs.com/cqb-learner/p/5866917.html
Copyright © 2011-2022 走看看