2016-01-12 22 views
13

私はちょっと立ち往生しており、助けが必要です。だからAFNetworking 2.0にはAFHTTPRequestOperationがありますので、私は簡単にNSOperationQueueを使用し、いくつかの依存関係があります。だから私たちは現在とNSURLSessionのサブクラスではないNSOperationです。私はサブクラスAFHTTPSessionManagerというクラスAPIClientを持っています。私はそのクラスをsharedClientというシングルトンとして使っています。AFNetworking 3.0 AFOTPSessionManager(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; 
} 

あなたはNSOperationとしてそれをラップするために(それが可能だ場合)そのように実装する方法任意のアイデアを持っていますか:例のGETは、このように見えるためので、私は、GETやPOSTをオーバーライドしていますか?だから、私は何をしたいのですか?2つのネットワークコールを同時に実行できるようにしたいのですが、その後、最初の2つのコールの2番目のネットワークコールに依存する別のメソッドコールがあります。何が最良のアプローチであるか考えていますか?

+0

ありがとうございました。ありがとうございました。ありがとうございます。 – Flipper

+0

ありがとうございました。はい、オハイオ州申し訳ありませんが、私は十分に私はそれを再度読むとき - 両方の要求に依存して明確ではなかった:) – Flipper

+0

あなたがこの答えでチェックできるよりもサーバー側で正確なエラーを取得したい場合 'http://stackoverflow.com/a/35723726/3463712 ' – Max

答えて

31

私は、サブクラスで要求をラップする簡単なクラスのセット(https://github.com/robertmryan/AFHTTPSessionOperation/)を作成しました。その後、それを使用して、maxConcurrentOperation制約、または操作の依存関係を楽しむことができます。例えば、ここで我々は2つの同時要求を発行し、これらの要求の両方の完了に依存して終了操作を持っている例

です:

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

それはあなたが唯一の2つの要求を扱っているので、ということは注目に値します、あなたも同じことを達成するために、ディスパッチグループを使用できます。ディスパッチグループと

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

を、あなただけのすべてのパスの両方successfailureブロックは0123呼び出す以内ように注意する必要があります。

+0

これはまさに私が探していたものです。素晴らしい: – Flipper

+0

@Flipper - BTW、私はこれらの外部クラスを導入したくない場合、GCDの代替案で回答を更新しました。 – Rob

+0

大変ありがとうございました。あなたのご協力ありがとうございました:) – Flipper

関連する問題