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(@"%@\n%@",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 [@"\r\n" 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);

    }];

}

```

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM