1. 程式人生 > >AFNetworking 檔案上傳Data,File圖片,檔案等上傳

AFNetworking 檔案上傳Data,File圖片,檔案等上傳

這段時間需要整理一些東西, 先備註在這裡, 將花時間把這個點整理一下。

使用AFNetworking上傳圖片,(可一次上傳多張圖片,包含不同型別png, jpeg)

使用AFNetworking上傳視訊

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    AFHTTPRequestOperation *operation = [manager POST:mutPath

                                           parameters:param

                            constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

                               if (mediaDatas.count > 0) {

                                    NSObject *firstObj = [mediaDatas objectAtIndexSafe:0];

                                   if ([firstObj isKindOfClass:[UIImage class]]) {    //

圖片

                                       for(NSInteger i=0; i<mediaDatas.count; i++) {

                                            UIImage *eachImg = [mediaDatas objectAtIndexSafe:i];

//NSData *eachImgData = UIImagePNGRepresentation(eachImg);

                                            NSData *eachImgData = UIImageJPEGRepresentation(eachImg, 0.5);

[formData appendPartWithFileData:eachImgData name:[NSString stringWithFormat:@"img%d", i+1] fileName:[NSString stringWithFormat:@"img%d.jpg", i+1] mimeType:@"image/jpeg"];

                                        }

                                    }else {        // 視訊

                                        ALAsset *asset = [mediaDatas objectAtIndexSafe:0];

                                        NBLog(@"asset=%@, representation=%@, url=%@", asset, [asset defaultRepresentation], [asset defaultRepresentation].url);

                                        if (asset !=nil) {

                                                NSString *videoPath = [NSDocumentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.mov", 0]];    // 這裡直接強制寫一個即可,之前計劃是用i++來區分不明視訊

                                                NSURL *url = [NSURL fileURLWithPath:videoPath];

                                                NSError *theErro =nil;

                                               BOOL exportResult = [asset exportDataToURL:url error:&theErro];

                                                NBLog(@"exportResult=%@", exportResult?@"YES":@"NO");

                                            NSData *videoData = [NSData dataWithContentsOfURL:url];

[formData appendPartWithFileData:videoData name:@"video1" fileName:@"video1.mov" mimeType:@"video/quicktime"];

                                            NBLog(@"method 2");

                                        }

                                    }

                                }

                            } success:^(AFHTTPRequestOperation *operation,id responseObject) {

                                NSDictionary *returnedDic = [XXBaseViewController parseResponseObj:responseObject];

                                NBLog(@"post Big success returnedDic=%@", returnedDic);

                            } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

                                NBLog(@"post big file fail error=%@", error);

                               if (errorBlock) {

                                    errorBlock(@{@"errorcode":@(error.code),@"errordomain":error.domain});

                                }

                            }];

    [operation setUploadProgressBlock:^(NSUInteger bytesWritten,long long totalBytesWritten,long long totalBytesExpectedToWrite) {

        NSLog(@"bytesWritten=%d, totalBytesWritten=%lld, totalBytesExpectedToWrite=%lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);

       if (xxProgressView != nil) {

            [xxProgressView setProgressViewTo:totalBytesWritten*1.0/totalBytesExpectedToWrite];

        }

    }];

1. 注意上面上傳圖片時時, 需要先轉為NSData, 然後再執行

[formData appendPartWithFileData:eachImgData name:[NSString stringWithFormat:@"img%d", i+1] fileName:[NSString stringWithFormat:@"img%d.jpg", i+1] mimeType:@"image/jpeg"];

執行這個方法時, name:部分是伺服器用來解析的欄位, 而fileName則是直接上傳上去的圖片, 注意一定要加 .jpg或者.png,(這個根據你得到這個imgData是通過jepg還是png的方式來獲取決定)。 然後mimeType值也要與上面的型別對應, 網上看到有的說直接寫成 @"image/*", 據說也是可以的, 沒驗證過。  但一定要注意的是這個fileName中.jpg和.png是一定要新增的。 否則伺服器可能會推斷這個圖片的型別, 推斷時就可能推斷錯誤, 而使得圖片上傳上去後,顯示不出來的問題。 我在做這個專案時就遇到了這樣的問題, 現象就是有時上傳成功,有時上傳失敗。 有時上傳上去3張圖,結果只顯示2張圖, 最後一張圖顯示不出來的, 可能就是因為伺服器推斷格式時推斷錯誤。 2. 對於上面的視訊檔案, 這裡使用的是ALAsset型別, 這個是通過

CTAssetsPickerController來選擇手機相簿中的視訊檔案的。

然後通過生成一個視訊檔名及地址, 並通過一個寫方法, 寫到該路徑下, 寫檔案如下。

- (BOOL) exportDataToURL: (NSURL*) fileURL error: (NSError**) error

{

    [[NSFileManager defaultManager] createFileAtPath:[fileURL path] contents:nil attributes:nil];

    NSFileHandle *handle = [NSFileHandle fileHandleForWritingToURL:fileURL error:error];

   if (!handle) {

       return NO;

    }

    ALAssetRepresentation *rep = [self defaultRepresentation];

    uint8_t *buffer = calloc(BufferSize,sizeof(*buffer));

    NSUInteger offset = 0, bytesRead = 0;

   do {

       @try {

            bytesRead = [rep getBytes:buffer fromOffset:offset length:BufferSize error:error];

            [handle writeData:[NSData dataWithBytesNoCopy:buffer length:bytesRead freeWhenDone:NO]];

            offset += bytesRead;

        }@catch (NSException *exception) {

            free(buffer);

           return NO;

        }

    }while (bytesRead > 0);

    free(buffer);

return YES;

}

把視訊寫入後,再通過NSData來取出這個視訊的資料。 並新增到這個AFHttpRequestOperation的Body中, 進行傳輸。

(估計這裡可能有更好的辦法來實現這個功能, 因為上面這個寫入檔案後,再轉成NSData感覺有些繁瑣,因為我曾嘗試過其它方法,如通過ALAsset來獲取到這個視訊檔案的url地址, 然後再通過NSData直接取這個地址,結果發現上傳給後臺後, 後臺並不能識別到這個視訊檔案,後臺能知道確實收到了視訊資料,但可能某些原因,使得前端再次去獲取該視訊檔案時,發現播放不了。具體原因可以再次去進行研究。

嘗試過程如下:

A:

上傳後,後臺僅獲取到文字

                                                ALAssetRepresentation *rep = [asset defaultRepresentation];

                                                Byte *buffer = (Byte*)malloc(rep.size);

                                                NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];

                                                NSData *videoData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];

//                                        [formData appendPartWithFormData:videoData name:@"video1"];

                                                [formData appendPartWithFileData:videoData name:@"video1" fileName:@"video1.mov" mimeType:@"video/quicktime"];

嘗試B:

通過NSURl來取到這個地址, 然後用NSData來取視訊, 然後再把這個視訊進行上傳。

有興趣的朋友可以繼續研究下去。 

注:上傳視訊時和上面的上傳圖片一樣,需要指定這個.mov, 及video/quicktime 型別指定。 前面的方法中要進行儲存到本地時, 檔名指定為%d.mov。