我試圖使用多部分表單數據使用- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;
方法上傳視頻/圖像文件。但不知何故,我無法上傳文件,我得到「stream ended unexpectedly
」錯誤。無法使用iOS中的NSURLSession多部分表單數據上傳文件
要求
- 上傳的視頻/圖像文件到服務器
- 應用程序應該支持後臺上傳(繼續應用進入後臺即使在上傳過程)
- 服務器預計該數據將使用多部分表單數據發送。
方法/ API的使用來實現這一
NSURLSession背景會話API(下面列出完整代碼)
2.
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL
挑戰/問題面臨着
- 我使用這個API上傳過程中每一次
點要注意
上傳越來越成功的代碼相同面臨着「
stream ended unexpectedly
」錯誤如果我使用NSURLConnection
而不是NSURLSession
。NSURLSession
後臺上傳過程預計文件位置(NSURL
)爲參數,不接受NSData。它不允許我們在上傳之前將文件轉換爲NSData
,即我們無法將NSData添加到文件正文。
需要幫助的以下幾點
是否有正在形成的多FORMDATA身體的任何錯誤(注 - 同樣的代碼與NSURLConnection的工作)
我的方法在哪裏出錯?
我們是否需要在服務器級別進行任何更改以支持
NSURLSession backgroundSession
上傳? (在數據解析或其他東西?)這裏是被用於上載文件
的NSString * BoundaryConstant = @ 「---------- V2ymHFg03ehbqgZCaKO6jy」 的代碼;
// string constant for the post parameter 'file'. My server uses this name: `file`. Your's may differ
NSString* FileParamConstant = @"file";
// the server url to which the image (or video) is uploaded. Use your server url here
url=[NSURL URLWithString:[NSString stringWithFormat:@"%@%@%d",baseURL,@"posts/post/update/",createPostObject.PostID]];
// create request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:120];
[request setHTTPMethod:@"POST"];
[request addValue:@"multipart/form-data" forHTTPHeaderField:@"Content-Type"];
[request setURL:url];
// set Content-Type in HTTP header
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", BoundaryConstant];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];
if([[NSUserDefaults standardUserDefaults] objectForKey:@"accessToken"]){
[request setValue:[[NSUserDefaults standardUserDefaults] objectForKey:@"accessToken"] forHTTPHeaderField:AccessTokenKey];
}
// post body
NSMutableData *body = [NSMutableData data];
// add params (all params are strings)
for (NSString *param in self.postParams) {
NSLog(@"param is %@",param);
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", [self.postParams objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
// add video file name to body
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"file.mp4\"\r\n", FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Type: video/mp4\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
// [body appendData:self.dataToPost];
[body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the request
[request setHTTPBody:body];
// set the content-length
NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[body length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
NSLog(@"Request body %@", [[NSString alloc] initWithData:[request HTTPBody] encoding:NSUTF8StringEncoding]);
NSURLSessionConfiguration * backgroundConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"backgroundtask1"];
NSURLSession *backgroundSeesion = [NSURLSession sessionWithConfiguration: backgroundConfig delegate:self delegateQueue: [NSOperationQueue mainQueue]];
NSURLSessionUploadTask *uploadTask = [backgroundSeesion uploadTaskWithRequest:request fromFile:self.videoUrl];
[uploadTask resume];
你似乎設置「內容 - 鍵入「兩次。不知道如何解決。不知道其餘的。我做了類似的事情,但是單獨創建上傳緩衝區(在C++函數中)並添加空洞緩衝區。所以,我不需要更多的貢獻。 –