使用NSOperation AFNetworking 3.0 AFHTTPSessionManager

Fli*_*per 14 objective-c ios afnetworking nsurlsession

我现在被困了一段时间,我需要帮助.所以在AFNetworking 2.0中我们AFHTTPRequestOperation可以轻松使用NSOperationQueue并拥有一些依赖关系.因此,只有我们现在拥有的是AFHTTPSessionManagerNSURLSession不继承NSOperation.我有类的APIClient子类AFHTTPSessionManager.我正在使用该类作为单身sharedClient.我已经覆盖了GET和POST,例如GET看起来像这样:

- (NSURLSessionDataTask *)GET:(NSString *)URLString
               parameters:(NSDictionary *)parameters
                  success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                  failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure {
NSURLSessionDataTask *task = [super GET:URLString parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
    success(task, responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    failure(task, [Response createErrorWithAFNetworkingError:error]);
}];

return task;
}
Run Code Online (Sandbox Code Playgroud)

您是否知道如何以这种方式实现(如果可能的话)将其包装为NSOperation?所以我想做什么 - 我希望能够并行运行两个网络呼叫,然后再进行另一个方法调用,这取决于前两个呼叫的第二次网络呼叫.你知道什么是最好的方法吗?

Rob*_*Rob 34

我编写了一组快速的小类(https://github.com/robertmryan/AFHTTPSessionOperation/),用于AFHTTPSessionManager在异步NSOperation子类中包装请求.然后,您可以使用它来享受maxConcurrentOperation约束或操作依赖性.

例如,这是一个示例,其中我们发出两个并发请求,并且完成操作取决于这两个请求的完成:

//  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
Run Code Online (Sandbox Code Playgroud)

值得注意的是,由于您只处理两个请求,您还可以使用调度组来完成同样的事情:

//  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
Run Code Online (Sandbox Code Playgroud)

使用调度组,您只需要小心调用successfailure调用块中的每个路径dispatch_group_leave.