9

Sto provando a caricare file di grandi dimensioni utilizzando AFNetworking e il caricamento continua quando l'applicazione è in background.Come caricare l'attività in background utilizzando una rete

posso caricare i file più che bene, ma quando tento di utilizzare una configurazione di fondo - l'applicazione si blocca con il seguente: stacktrace Eccezione: EXC_BAD_ACCESS (codice = 1, indirizzo = 0x8000001f))

_CFStreamSetDispatchQueue 
-[__NSCFBackgroundDataTask captureStream:] 
__70-[__NSCFBackgroundDataTask _onqueue_needNewBodyStream:withCompletion:]_block_invoke_2 
_dispatch_call_block_and_release 
_dispatch_queue_drain 
_dispatch_queue_invoke 
_dispatch_root_queue_drain 
_dispatch_worker_thread3 
_pthread_wqthread 

Ecco alcuni esempi di codice:

Nota: quando utilizzo lo [NSURLSessionConfiguration defaultSessionConfiguration], il caricamento ha esito positivo, ma non continuerà quando l'applicazione è in background. [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.company.appname.uploadservice"] causa l'arresto anomalo dell'applicazione.

NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[uploadBundle.uploadUrl absoluteString] parameters:[uploadBundle getParameters] constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { 
    [formData appendPartWithFileURL:uploadBundle.fileDataUrl name:uploadBundle.fileName fileName:uploadBundle.fileName mimeType:uploadBundle.mimeType error:nil]; 
} error:nil]; 

Authentication *authentication = [Authentication getInstance]; 
[request addValue:authentication.token forHTTPHeaderField:@"token"]; 
[request addValue:authentication.authorization forHTTPHeaderField:@"Authorization"]; 

//NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; 
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.company.appname.uploadservice"]; 
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; 

NSProgress *progress = nil; 
_currentUploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { 
    if (error) { 
     NSLog(@"Error: %@", error); 
    } else { 
     NSLog(@"%@ %@", response, responseObject); 
    } 
}]; 
+1

Ehi hai trovato qualche soluzione? Sto affrontando lo stesso problema. Mi aiuti per favore. –

risposta

7

Sto rispondendo alla mia domanda nella speranza che possa aiutare alcune persone.

Non riesco a trovare questo documento ovunque, ma sembra che sia necessario utilizzare uploadTaskWithRequest:fromFile:progress:completionHandler: quando si utilizza una configurazione di sessione in background.

Ecco un semplice esempio:

AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate]; 

id config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.opentext.core.uploadservice"]; 
id session = [NSURLSession sessionWithConfiguration:config delegate:appDelegate delegateQueue:[NSOperationQueue new]]; 

OMGMultipartFormData *multipartFormData = [OMGMultipartFormData new]; 
//[multipartFormData addFile:data parameterName:@"file" filename:nil contentType:nil]; 
[multipartFormData addParameters:[uploadBundle getParameters]]; 

NSURLRequest *rq = [OMGHTTPURLRQ POST:[uploadBundle.uploadUrl absoluteString] :multipartFormData]; 

id path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"upload.NSData"]; 
[rq.HTTPBody writeToFile:path atomically:YES]; 

[[session uploadTaskWithRequest:rq fromFile:[NSURL fileURLWithPath:path]] resume]; 
+0

Ho anche lo stesso problema che hai sollevato sopra. Nel mio caso ho bisogno di caricare più file in una singola richiesta. In questo modo è possibile allegare più file a una singola richiesta? – Inoka

+0

Puoi condividere i file OMGMultipartFormData che ho provato a trovarlo ma non l'ho ottenuto. –

+4

questa risposta non è chiara. Cos'è 'uploadBundle'? E cosa stai cercando di fare con la riga 'percorso id '? – Raptor

0

I problemi sembra essere che si sta tentando di utilizzare una "richiesta di streaming" invece di file. Il codice funziona con

NSURLSessionUploadTask * uploadTask = [direttore uploadTaskWithRequest: Richiesta fromfile: [NSURL fileURLWithPath: filePath] progresso: & progresso completionHandler:^(NSURLResponse * risposta, id responseObject, NSError * errore) {

. ... }];

metodo senza problemi. Ho anche scoperto che se si tenta di utilizzare i dati del file anziché il file effettivo (con uploadTaskWithRequest: fromData: progress: completionHandler :), il caricamento fallisce come spiegato in Upload tasks from NSData are not supported in background sessions

+0

Quindi puoi caricare un solo file alla volta? Nessun equivalente multipartFormData? – shim

+3

È possibile caricare dati multipart, solo che è necessario salvare i dati multipart in un file e quindi caricare il file.Poi, [serializzatore requestWithMultipartFormRequest: Richiesta writingStreamContentsToFile: filePathtemp completionHandler:^(NSError * errore) { NSURLSessionUploadTask * uploadTask = [self.activeSessionManager uploadTaskWithRequest: Richiesta fromfile: progresso filePathtemp: & progresso completionHandler:^(NSURLResponse * risposta, id responseObject, NSError * errore) { }]; [uploadTask resume]; }]; – tuttu47

Problemi correlati