80

私のプロジェクトはAFNetworkingを使用しています。

https://github.com/AFNetworking/AFNetworking

タイムアウトをダイヤルダウンするにはどうすればよいですか?インターネットに接続されていないATMは、約2分間、フェイルブロックがトリガーされません。長い間Waay....

4

9 に答える 9

110

タイムアウト間隔を変更することは、あなたが説明している問題に対する最良の解決策ではないことはほぼ確実です。代わりに、HTTP クライアントが到達不能になったネットワークを処理することを実際に望んでいるように思えますね。

AFHTTPClientには、インターネット接続が失われたときに通知するメカニズムが組み込まれています-setReachabilityStatusChangeBlock:

低速のネットワークでは、リクエストに時間がかかる場合があります。iOS が遅い接続に対処する方法を知っていることを信頼し、それとまったく接続していないことの違いを判断する方がよいでしょう。


このスレッドで言及されている他のアプローチを避けるべき理由についての私の推論を拡張するために、いくつかの考えを以下に示します。

  • リクエストは、開始前であってもキャンセルできます。リクエストをキューに入れても、実際にいつ開始されるかは保証されません。
  • タイムアウト間隔は、実行時間の長いリクエスト (特に POST) をキャンセルすべきではありません。100MB の動画をダウンロードまたはアップロードしようとしているとします。要求が低速の 3G ネットワークで可能な限り順調に進んでいるのに、予想よりも少し時間がかかっているのに、なぜ要求を不必要に停止するのでしょうか?
  • マルチperformSelector:afterDelay:...スレッド アプリケーションでは危険な場合があります。これにより、あいまいでデバッグが困難な競合状態が発生する可能性があります。
于 2012-04-08T20:22:52.183 に答える
44

上記のマットの回答を見ることを強くお勧めします-この回答は、彼が一般的に言及している問題に反するものではありませんが、元のポスターの質問については、到達可能性を確認する方がはるかに適しています。

ただし、それでもタイムアウトを設定したい場合 (performSelector:afterDelay:その他に内在するすべての問題がない場合、プルリクエスト Lego はこれを行う方法をコメントの 1 つとして説明しています。次のようにします。

NSMutableURLRequest *request = [client requestWithMethod:@"GET" path:@"/" parameters:nil];
[request setTimeoutInterval:120];

AFHTTPRequestOperation *operation = [client HTTPRequestOperationWithRequest:request success:^{...} failure:^{...}];
[client enqueueHTTPRequestOperation:operation];

ただし、@KCHarwood は、Apple が POST リクエストに対してこれを変更することを許可していないように見えるという警告を参照してください (これは iOS 6 以降で修正されています)。

@ChrisopherPickslay が指摘しているように、これは全体的なタイムアウトではなく、データの受信 (または送信) 間のタイムアウトです。全体的なタイムアウトを賢明に行う方法を知りません。setTimeoutInterval の Apple ドキュメントには次のように書かれています。

秒単位のタイムアウト間隔。接続の試行中にリクエストがタイムアウト間隔よりも長くアイドル状態のままである場合、リクエストはタイムアウトしたと見なされます。デフォルトのタイムアウト間隔は 60 秒です。

于 2012-01-03T15:24:54.397 に答える
28

requestSerializer setTimeoutInterval メソッドを介してタイムアウト間隔を設定できます。AFHTTPRequestOperationManager インスタンスから requestSerializer を取得できます。

たとえば、25 秒のタイムアウトでポスト リクエストを実行するには、次のようにします。

    NSDictionary *params = @{@"par1": @"value1",
                         @"par2": @"value2"};

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    [manager.requestSerializer setTimeoutInterval:25];  //Time out after 25 seconds

    [manager POST:@"URL" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {

    //Success call back bock
    NSLog(@"Request completed with response: %@", responseObject);


    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
     //Failure callback block. This block may be called due to time out or any other failure reason
    }];
于 2014-07-16T21:52:04.193 に答える
7

現時点では、手動でパッチを適用する必要があると思います。

私は AFHTTPClient をサブクラス化し、変更しました

- (NSMutableURLRequest *)requestWithMethod:(NSString *)method path:(NSString *)path parameters:(NSDictionary *)parameters

追加する方法

[request setTimeoutInterval:10.0];

AFHTTPClient.mの 236 行目です。もちろん、それが構成できれば良いのですが、現時点では不可能であることがわかります。

于 2011-11-29T09:42:23.050 に答える
5

関連するプロジェクトの問題に関する他の人の回答と@matttの提案に基づいて、サブクラス化する場合のドロップインクイックを次に示しますAFHTTPClient

@implementation SomeAPIClient // subclass of AFHTTPClient

// ...

- (NSMutableURLRequest *)requestWithMethod:(NSString *)method path:(NSString *)path parameters:(NSDictionary *)parameters {
  NSMutableURLRequest *request = [super requestWithMethod:method path:path parameters:parameters];
  [request setTimeoutInterval:120];
  return request;
}

- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method path:(NSString *)path parameters:(NSDictionary *)parameters constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block {
  NSMutableURLRequest *request = [super requestWithMethod:method path:path parameters:parameters];
  [request setTimeoutInterval:120];
  return request;
}

@end

iOS 6 で動作確認済み。

于 2013-03-13T20:19:18.943 に答える
0

次のようなタイマーでこれを行うことはできませんか:

.h ファイル内

{
NSInteger time;
AFJSONRequestOperation *operation;
}

.m ファイル内

-(void)AFNetworkingmethod{

    time = 0;

    NSTtimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(startTimer:) userInfo:nil repeats:YES];
    [timer fire];


    operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        [self operationDidFinishLoading:JSON];
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        [self operationDidFailWithError:error];
    }];
    [operation setJSONReadingOptions:NSJSONReadingMutableContainers];
    [operation start];
}

-(void)startTimer:(NSTimer *)someTimer{
    if (time == 15&&![operation isFinished]) {
        time = 0;
        [operation invalidate];
        [operation cancel];
        NSLog(@"Timeout");
        return;
    }
    ++time;
}
于 2013-09-29T16:12:55.883 に答える