iOS 開發之--使用AFNetWorking3.1.0上傳單張/多張圖片

在調試接口的時候,遇到一個問題,就是多張圖片上傳的時候,無論我上傳多少張,只會上傳成功最後一張,也就是說只有一張圖片上傳成功了,針對這個問題,經過查找資料,找到了緣由,首先,在上傳的過程當中,咱們獲取到本地的image,會放到一個數組裏面,在請求方法內進行上傳,也就是說接口只調用一次,可是圖片是在遍歷完成後,一次性上傳成功,如今的話,php後臺的循環邏輯出現問題,走的仍是單張上傳邏輯,只是在外層添加了一個循環,這就直接致使了問題的存在,固然安卓那邊是正常的,針對這種狀況,有兩種解決方法:php

1,在php端,優化多張圖片上傳邏輯,而後兼容下單張上傳的接口,html

2,就是在ios端的上傳多張圖片的接口,進行代碼的優化,把請求提內的遍歷,放到外層,而後每上傳一張圖片就調用一次接口,固然這是種笨辦法,由於php後臺沒法及時處理,只能在前臺作優化了,ios

找後臺調試後發現,經過上面的方法上傳多張圖片,實際上只有一張被傳到後臺,可能的緣由是:git

上傳多張圖片時,因爲url的參數沒有變化,iOS默認是同一個請求,只發送了一次請求給後臺,故後臺只收到一張圖片。github

廢話不說了,直接上代碼:json

正常的上傳圖片的方法:數組

        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        manager.requestSerializer.timeoutInterval = 20;
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"multipart/form-data", @"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", nil];

        [manager POST:[NSString stringWithFormat:@"%@%@",HostUrl,getInfoPhoto] parameters:parameterDict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            
            // formData: 專門用於拼接須要上傳的數據,在此位置生成一個要上傳的數據體
            // 這裏的_photoArr是你存放圖片的數組
            for (int i = 0; i < headImage.count; i++) {
                
                UIImage *image = headImage[i];
                NSData *imageData = UIImageJPEGRepresentation(image, 0.5);
                
                // 在網絡開發中,上傳文件時,是文件不容許被覆蓋,文件重名
                // 要解決此問題,
                // 能夠在上傳時使用當前的系統事件做爲文件名
                NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                // 設置時間格式
                [formatter setDateFormat:@"yyyyMMddHHmmss"];
                NSString *dateString = [formatter stringFromDate:[NSDate date]];
                NSString *fileName = [NSString  stringWithFormat:@"%@.jpg", dateString];
                /*
                 *該方法的參數
                 1. appendPartWithFileData:要上傳的照片[二進制流]
                 2. name:對應網站上[upload.php中]處理文件的字段(好比upload)
                 3. fileName:要保存在服務器上的文件名
                 4. mimeType:上傳的文件的類型
                 */
                [formData appendPartWithFileData:imageData name:@"upload" fileName:fileName mimeType:@"image/jpeg"]; //
            }

            
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            
            //上傳進度
            dispatch_sync(dispatch_get_main_queue(), ^{
                NSLog(@"progress is %@",uploadProgress);
            });
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            success(responseObject);
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            failure(error);
            
        }];

 

而後處理事後的代碼:緩存

 // 上傳多張圖片
        for(NSInteger i = 0; i < headImage.count; i++)
        {
            AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
            manager.requestSerializer.timeoutInterval = 20;
            manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"multipart/form-data", @"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", nil];

            __block NSInteger blockI = i;
            [manager POST:[NSString stringWithFormat:@"%@%@",HostUrl,getInfoPhoto] parameters:parameterDict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
                //取出單張圖片二進制數據
                id obj = headImage[blockI];
                UIImage *image = nil;
                if ([obj isKindOfClass:[UIImage class]]) {
                    image = (UIImage *)obj;
                }else{
                    image = [UIImage imageWithContentsOfFile:obj];
                }
                if (image) {

                    UIImage *image = headImage[i];
                    NSData *imageData = UIImageJPEGRepresentation(image, 0.5);
                    
                    // 在網絡開發中,上傳文件時,是文件不容許被覆蓋,文件重名
                    // 要解決此問題,
                    // 能夠在上傳時使用當前的系統事件做爲文件名
                    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                    // 設置時間格式
                    [formatter setDateFormat:@"yyyyMMddHHmmss"];
                    NSString *dateString = [formatter stringFromDate:[NSDate date]];
                    NSString *fileName = [NSString  stringWithFormat:@"%@.jpg", dateString];
                    /*
                     *該方法的參數
                     1. appendPartWithFileData:要上傳的照片[二進制流]
                     2. name:對應網站上[upload.php中]處理文件的字段(好比upload)
                     3. fileName:要保存在服務器上的文件名
                     4. mimeType:上傳的文件的類型
                     */
                    [formData appendPartWithFileData:imageData name:@"upload" fileName:fileName mimeType:@"image/jpeg"]; //

                    
                }
            } progress:^(NSProgress * _Nonnull uploadProgress) {
                
                NSLog(@"progress is %@",uploadProgress);
                
            } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                
                success(responseObject);
                
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                failure(error);
            }];  
        }

循環調用接口,必然是不合理,不過在這裏只談問題的解決!服務器

 

補:另外若是使用AFN,我推薦一個很是牛的封裝類,裏面把處理緩存的機制加上了,連接以下:網絡

簡書地址:http://www.jianshu.com/p/c695d20d95cb

GitHub地址:https://github.com/jkpang/PPNetworkHelper

相關文章
相關標籤/搜索