servicio consumir ios objective-c cocoa-touch asynchronous httprequest

ios - consumir - Espere hasta que se hayan ejecutado varias solicitudes de red, incluidos sus bloques de finalizaciĆ³n



consumir servicio rest swift 4 (4)

AFNetworking ha diseñado un método para este tipo de operaciones, que se abstrae de GCD:

-enqueueBatchOfHTTPRequestOperationsWithRequests:progressBlock:completionBlock:

-enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock:

Eche un vistazo a las FAQ

Tengo varias operaciones (son solicitudes de AFNetworking) con bloques de finalización que tardan un poco en ejecutarse, y un objeto de Core Data que se debe guardar al final de todas las solicitudes.

MyCoreDataObject *coreDataObject; AFHTTPRequestOperation *operation1 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute1 = responseObject; sleep(5); }]; [operation1 start]; AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute2 = responseObject; sleep(10); }]; [operation1 operation2]; [context save:nil];

Por supuesto, esto no funciona como yo quiero porque las solicitudes son asincrónicas. Traté de agregar un NSOperationQueue así:

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init]; [operationQueue setMaxConcurrentOperationCount:2]; AFHTTPRequestOperation *operation1 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute1 = responseObject; sleep(5); }]; [operationQueue addOperation:operation1]; AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute2 = responseObject; sleep(10); }]; [operationQueue addOperation:operation2]; [imageQueue waitUntilAllOperationsAreFinished]; [context save:nil];

Esto se ve un poco mejor. Al utilizar waitUntilAllOperationsAreFinished , mi cola bloquea el hilo actual hasta que mis solicitudes finalicen, pero no hasta que mis bloques de éxito hayan finalizado, que es realmente lo que necesito.

¿Alguna idea sobre cómo lograr esto de una buena manera?


Creo algo como esto:

NSMutableArray *mutableOperations = [NSMutableArray array]; for (NSURL *fileURL in filesToUpload) { NSURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { [formData appendPartWithFileURL:fileURL name:@"images[]" error:nil]; }]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; [mutableOperations addObject:operation]; } NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:@[...] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) { NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations); } completionBlock:^(NSArray *operations) { NSLog(@"All operations in batch complete"); }]; [[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];

refiriéndose a los documentos: http://cocoadocs.org/docsets/AFNetworking/2.5.0/


Mis requisitos eran los de hacer muchas solicitudes de una matriz de String (URL)

func updateSourceData(element: Int) { if element > availableUrls.count - 1 { return } let service = SourceDataServiceDao() let currentUrl = availableUrls[element] service.fooCall(url: currentUrl, completion: { (response, error) -> Void in self.updateSourceData(element + 1) }) }

Obviamente, de esta forma las llamadas se realizan en cascada, no en N llamadas asincrónicas.


Use grupos de despacho.

dispatch_group_t group = dispatch_group_create(); MyCoreDataObject *coreDataObject; dispatch_group_enter(group); AFHTTPRequestOperation *operation1 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute1 = responseObject; sleep(5); dispatch_group_leave(group); }]; [operation1 start]; dispatch_group_enter(group); AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { coreDataObject.attribute2 = responseObject; sleep(10); dispatch_group_leave(group); }]; [operation2 start]; dispatch_group_wait(group, DISPATCH_TIME_FOREVER); dispatch_release(group); [context save:nil];