1. 程式人生 > >iOS 使用AFNetworking進行下載和上傳

iOS 使用AFNetworking進行下載和上傳

AFNetworking為我們提供了太多的方便,今天說一下用AFNetworking進行檔案的下載和上傳,AFNetworking的引入就不多說了

首先,在storyboard的view上新增一個imageview和一個button,分別增加輸出口和點選事件



ViewController.m中引入標頭檔案#import<AFNetworking.h>

然後在button點選事件中加入下載方法

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    NSURL *URL = [NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504497234144&di=a3169e58078bb55ae38bfc99fd18f17e&imgtype=jpg&src=http%3A%2F%2Fg.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F8694a4c27d1ed21bd85def25a46eddc450da3f5e.jpg"];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress *downloadProgress){
//        這個block裡面獲取下載進度
        [SVProgressHUD showProgress:(CGFloat)downloadProgress.completedUnitCount/(CGFloat)downloadProgress.totalUnitCount status:@"下載中"];
    } destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
//        這個block裡面返回下載檔案存放路徑
        if([self isFileExist:[response suggestedFilename]]) {
            NSLog(@"檔案已存在");
        }
        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
//        [response suggestedFilename]為檔名
        NSURL *url = [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
        return url;
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
//        這個block裡面拿到下載結果
        NSData *data = [NSData dataWithContentsOfURL:filePath];
        UIImage *img = [UIImage imageWithData:data];
        self.imageView.image = img;
        
        [SVProgressHUD dismissWithDelay:0.0 completion:nil];
    }];
    [downloadTask resume];


判斷將要下載檔案是否已存在

//判斷檔案是否已經在沙盒中存在
-(BOOL) isFileExist:(NSString *)fileName
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [paths objectAtIndex:0];
    NSString *filePath = [path stringByAppendingPathComponent:fileName];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL result = [fileManager fileExistsAtPath:filePath];
    NSLog(@"這個檔案已經存在:%@",
[email protected]
"是的":@"不存在"); return result; }

上傳,因為沒有伺服器,就只能把自己用過的方法寫下來,希望能對需要的朋友有所幫助

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    [manager POST:@"https://pan.baidu.com/disk/home#list/vmode=list&path=%2Fsz" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        //        self.fileName為要上傳檔案的檔名
        NSURL *filePath = [documentsDirectoryURL URLByAppendingPathComponent:self.fileName];
        //上傳
        /*
         此方法引數
         1. 要上傳的data資料
         2. 後臺處理檔案的欄位,若沒有可為空
         3. 要儲存在伺服器上的[檔名]
         4. 上傳檔案的[mimeType]
         application/octet-stream為通用型
         */
//        [formData appendPartWithFileData:fileData name:@"file" fileName:self.fileName mimeType:@"application/octet-stream"];
        
        /*
         此方法引數
         1. 要上傳的檔案路徑
         2. 後臺處理檔案的欄位,若沒有可為空
         3. 要儲存在伺服器上的[檔名]
         4. 上傳檔案的[mimeType]
         application/octet-stream為通用型
         */
        [formData appendPartWithFileURL:filePath name:@"file" fileName:self.fileName mimeType:@"application/octet-stream" error:nil];
        //個人比較建議用第二種,傳檔案路徑,因為自己做上傳當時的場景是把wps編輯後的文件上傳到伺服器,因為回傳回來的是一個字典,我就直接將字典內容解析出來轉成data資料,但是上傳到伺服器後文檔開啟時提示檔案損壞,下載下來開啟是亂碼,推測應該是wps回傳回來的資料裡應該有自己的一些編碼在裡面,導致直接上傳data資料會出現後臺解析錯誤的問題,後來把回傳回來的資料轉成檔案之後,再用檔案路徑方法上傳就沒問題了。
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [SVProgressHUD showSuccessWithStatus:@"上傳成功"];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [SVProgressHUD showErrorWithStatus:@"上傳失敗"];
    }];

上面的上傳地址是我自己的百度雲盤,雖然沒報錯,但是沒上傳到雲盤裡,只是作為示範。

demo下載地址