Sto tentando di caricare un file video/immagine utilizzando il metodo - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;
utilizzando dati di modulo multiparte. Ma in qualche modo non sono in grado di caricare il file e sto ricevendo l'errore "stream ended unexpectedly
".impossibile caricare il file utilizzando NSURLSession dati modulo in più parti in iOS
Requisiti
- caricare un file video/immagini al server
- App dovrebbe sostenere arrivi di fondo (Continua il processo di caricamento, anche dopo applicazione va in fondo)
- Server prevede i dati siano inviato utilizzando dati di moduli multiparte.
Metodi/API utilizzate per raggiungere questo
NSURLSession sfondo sessione API (completo del codice di seguito elencati)
2.
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL
Sfide/Problemi di fronte
- fronte di errore "
stream ended unexpectedly
" ogni volta che sto usando questa API per processo di caricamento
Punti da notare
Il caricamento sta ottenendo successo con lo stesso codice se uso
NSURLConnection
anzichéNSURLSession
.NSURLSession
processo di caricamento in background si aspetta che il percorso del file (NSURL
) come parametro, non accetta NSData. Non ci consente di convertire il file inNSData
prima di caricarlo, ad esempio, non possiamo aggiungere NSData al corpo del file.
bisogno di aiuto seguenti punti
C'è qualche errore nel corpo formdata multipart che si sta formando (nota - Lo stesso codice sta lavorando con NSURLConnection)
Dove sto sbagliando nel mio approccio?
È necessario apportare modifiche a livello di server per supportare i caricamenti
NSURLSession backgroundSession
? (nell'analisi dei dati o qualcos'altro?)Qui è il codice che viene utilizzato per il caricamento di un file
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];
Lei sembra di impostare "Content Scrivi "due volte. Non sono sicuro di come funzioni. Non sono sicuro del resto. Faccio qualcosa di simile, ma creo il buffer di caricamento separato (in una funzione C++) e aggiungo solo il buffer dei buchi. Quindi, non ho molto di più per contribuire con. –