2016-01-12 20 views
13

Tôi bị kẹt một thời gian và tôi cần trợ giúp. Vì vậy, trong AFNetworking 2.0, chúng tôi có AFHTTPRequestOperation vì vậy tôi có thể dễ dàng sử dụng NSOperationQueue và có một số phụ thuộc. Vì vậy, những gì chúng tôi có bây giờ chỉ là AFHTTPSessionManagerNSURLSession không phân loại NSOperation. Tôi có lớp học APIClient mà lớp con AFHTTPSessionManager. Tôi đang sử dụng lớp đó như singleton là sharedClient. Tôi đã overriden GET và POST ví dụ như vậy GET trông này:AFNetworking 3.0 AFHTTPSessionQuản lý sử dụng NSOperation

- (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; 
} 

Bạn có bất cứ ý tưởng làm thế nào để thực hiện theo cách đó (nếu có thể) để quấn mà như NSOperation? Vì vậy, những gì tôi muốn làm - Tôi muốn để có thể chạy song song hai cuộc gọi mạng, và sau đó có một cuộc gọi phương thức phụ thuộc vào cuộc gọi mạng thứ hai của hai cuộc gọi đầu tiên. Bạn có bất cứ ý tưởng gì sẽ là cách tiếp cận tốt nhất?

+0

Có, xin vui lòng, nếu bạn không nhớ – Flipper

+0

Cảm ơn bạn rất nhiều. Có, xin lỗi, tôi không đủ rõ ràng khi đọc lại - phụ thuộc vào cả hai yêu cầu :) – Flipper

+0

nếu bạn muốn nhận lỗi chính xác ở phía máy chủ hơn bạn có thể kiểm tra câu trả lời này 'http://stackoverflow.com/a/35723726/3463712 ' – Max

Trả lời

31

Tôi đã viết một tập hợp nhanh các lớp học (https://github.com/robertmryan/AFHTTPSessionOperation/) bao gồm AFHTTPSessionManager yêu cầu trong không đồng bộ NSOperation phân lớp. Sau đó bạn có thể sử dụng để tận hưởng các ràng buộc maxConcurrentOperation hoặc phụ thuộc hoạt động.

Ví dụ, đây là một ví dụ mà chúng tôi đưa ra hai yêu cầu đồng thời và có một hoạt động hoàn phụ thuộc vào hoàn tất cả những yêu cầu:

// 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 

Nó đáng chú ý là kể từ khi bạn chỉ đối phó với hai yêu cầu , bạn cũng có thể sử dụng các nhóm công văn để thực hiện điều tương tự:

// 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 

với các nhóm công văn, bạn chỉ cần phải cẩn thận rằng mọi con đường trong cả successfailure khối gọi dispatch_group_leave.

+0

Đó là chính xác những gì tôi đang tìm kiếm, tuyệt vời :) – Flipper

+0

@Flipper - BTW, tôi đã cập nhật câu trả lời với GCD thay thế nếu bạn không muốn giới thiệu những lớp học bên ngoài. – Rob

+0

Tuyệt vời, cảm ơn bạn rất nhiều vì đã giúp đỡ của bạn :) – Flipper

Các vấn đề liên quan