AFNetworking 3.0 AFHTTPSessionManager using NSOperation

后端 未结 1 1934
青春惊慌失措
青春惊慌失措 2020-12-14 03:44

I\'m stuck now some time and I need help. So in AFNetworking 2.0 we have AFHTTPRequestOperation so I could easily use NSOperationQueue and have som

相关标签:
1条回答
  • 2020-12-14 04:39

    I've written a quick little set of classes (https://github.com/robertmryan/AFHTTPSessionOperation/) that wrap AFHTTPSessionManager requests in asynchronous NSOperation subclass. You can then use that to enjoy maxConcurrentOperation constraints, or operation dependencies.

    For example, here's an example where we issue two concurrent requests and have a completion operation dependent upon completion of both of those requests:

    //  ViewController.m
    
    #import "ViewController.h"
    #import "AFNetworking.h"
    #import "AFHTTPSessionOperation.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        NSString *urlString1 = @"...";
        NSString *urlString2 = @"...";
    
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        queue.name = @"AFHTTPSessionManager queue";
    
        NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"All done");
        }];
    
        NSOperation *op1 = [AFHTTPSessionOperation operationWithManager:manager HTTPMethod:@"GET" URLString:urlString1 parameters:nil uploadProgress:nil downloadProgress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
            NSLog(@"finished 1");
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            NSLog(@"failed 1 - error = %@", error.localizedDescription);
        }];
        [completionOperation addDependency:op1];
    
        NSOperation *op2 = [AFHTTPSessionOperation operationWithManager:manager HTTPMethod:@"GET" URLString:urlString2 parameters:nil uploadProgress:nil downloadProgress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
            NSLog(@"finished 2");
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            NSLog(@"failed 2 - error = %@", error.localizedDescription);
        }];
        [completionOperation addDependency:op2];
    
        [queue addOperations:@[op1, op2] waitUntilFinished:false];
        [[NSOperationQueue mainQueue] addOperation:completionOperation];  // do this on whatever queue you want, but often you're updating UI or model objects, in which case you'd use the main queue
    }
    
    @end
    

    It's worth noting that since you're only dealing with two requests, you could also use dispatch groups to accomplish the same thing:

    //  ViewController.m
    
    #import "ViewController.h"
    #import "AFNetworking.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        NSString *urlString1 = @"...";
        NSString *urlString2 = @"...";
    
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
        dispatch_group_t group = dispatch_group_create();
    
        dispatch_group_enter(group);
        [manager GET:urlString1 parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"finished 1");
            dispatch_group_leave(group);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"failed 1 - error = %@", error.localizedDescription);
            dispatch_group_leave(group);
        }];
    
        dispatch_group_enter(group);
        [manager GET:urlString2 parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"finished 2");
            dispatch_group_leave(group);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"failed 2 - error = %@", error.localizedDescription);
            dispatch_group_leave(group);
        }];
    
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            NSLog(@"All done");
        });
    }
    
    @end
    

    With dispatch groups, you just need to be careful that every path within both the success and failure blocks call dispatch_group_leave.

    0 讨论(0)
提交回复
热议问题