3

AFNetworking を使用して、サードパーティ クラスで解析されたデータをダウンロードしています。AFNetworking を使用して同様のアクションを何度も実行しましたが、何らかの理由で、downloadProgressBlock を呼び出してプログレス バーで使用する計算を行うと、数値が負の値を返します。下記参照:

2013-09-22 16:04:06.036 Portland Police[2228:60b] Download = -31849.000000
2013-09-22 16:04:06.041 Portland Police[2228:60b] Download = -40537.000000
2013-09-22 16:04:06.042 Portland Police[2228:60b] Download = -44881.000000
2013-09-22 16:04:06.044 Portland Police[2228:60b] Download = -53569.000000
2013-09-22 16:04:06.046 Portland Police[2228:60b] Download = -62257.000000
2013-09-22 16:04:06.048 Portland Police[2228:60b] Download = -63705.000000
2013-09-22 16:04:06.085 Portland Police[2228:60b] Download = -70945.000000
2013-09-22 16:04:06.087 Portland Police[2228:60b] Download = -89769.000000
2013-09-22 16:04:06.089 Portland Police[2228:60b] Download = -94113.000000
2013-09-22 16:04:06.100 Portland Police[2228:60b] Download = -98457.000000
2013-09-22 16:04:06.104 Portland Police[2228:60b] Download = -102801.000000
2013-09-22 16:04:06.111 Portland Police[2228:60b] Download = 1.000000

以下は私のコードです:

// Get the URL we are going to use to parse with
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.portlandonline.com/scripts/911incidents.cfm"]];
NSURLRequest *request = [httpClient requestWithMethod:@"GET" path:nil parameters:nil];
AFHTTPRequestOperation *operation = [httpClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {

    NSLog(@"Response = %@", operation);

    // Empty our calls out
    [self.originalArray removeAllObjects];

    // Initiate our parser
    MWFeedParser *parser = [[MWFeedParser alloc] init];
    parser.delegate = self;
    [parser startParsingData:responseObject textEncodingName:[operation.response textEncodingName] withCompletionHandler:^(NSError *error, MWFeedParser *parser) {

        // If theres no error
        if (!error) {

            // Return the success block
            success(operation.request, operation.request.URL, self.calls);
        }
        else {

            // Return the failure block
            failure(operation.request, operation.request.URL, error);
        }
    }];

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    NSLog(@"AFHTTPRequestOperation Failure: %@", error);

    // Return our failure block
    failure(operation.request, operation.request.URL, error);
}];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {

    NSLog(@"Download = %f", (float)totalBytesRead / totalBytesExpectedToRead);

}];
[operation start];
4

1 に答える 1

7

問題はtotalBytesExpectedToRead. 具体的には、これは、ドキュメントが言うように、プロパティからNSURLResponse来ます:expectedContentLength

戻り値

受信者の予想されるコンテンツの長さ、またはNSURLResponseUnknownLength長さを特定できない場合。

討論

一部のプロトコル実装は、コンテンツの長さを応答の一部として報告しますが、すべてのプロトコルがその量のデータの配信を保証するわけではありません。クライアントは、多かれ少なかれデータを処理できるように準備する必要があります。

ちなみに、この定数NSURLResponseUnknownLengthは -1 に等しいので、計算値を説明できます。これは、応答の長さを判別できなかったことをシステムが通知する方法です。

したがって、最悪のシナリオでは、予想されるバイト数として -1 を取得します。-1 でなくても、完全に信頼できるわけではありません (特に、独自のサーバー コードを作成した場合は問題になります)。expectedContentLengthアプリは、アプリに報告されたものを適切に処理する必要があります。ほとんどの場合、負でない値を取得している場合は、通常、「完了率」の計算に効果的に使用できる値を取得していますが、それに依存しないでください (たとえば、より多くのバイトを受け取る可能性があります)。またはexpectedContentLengthレポートよりバイト数が少ない)。例外的な値を適切に処理します。

たとえば、進行状況バーを設定するときは、次のようにしました。

CGFloat progress;

if (expectedContentLength > 0 && progressContentLength <= expectedContentLength)
     progress = (CGFloat) progressContentLength / expectedContentLength;
else
     progress = (progressContentLength % 1000000l) / 1000000.0f;

これにより、予想されるコンテンツの長さの値が適切である場合、ダウンロードが進むにつれてゆっくりと 100% まで進行する進行状況バーが表示されますが、それ以外の場合は、1,000,000 バイトのダウンロードごとに 0% から 100% まで進行する進行状況バーが表示されます。この後者のシナリオは理想的ではありませんが、サーバーが予想されるコンテンツの長さを正確に報告しない限り、できることはあまりありません。

または、信頼できる が得られない場合は、この問題を完全に回避expectedContentLengthする不確定な進行状況ビュー (例: ) を使用することを選択できます。UIActivityIndicatorView

要するに、進行状況の計算が成功するかどうかは、サーバーが期待されるバイト数に対して正当な値を提供しているかどうかにかかっています。を見るとtotalBytesExpectedToRead、おそらく -1 を取得しており、その結果として興味深い計算された進行状況のパーセンテージ値が表示されます。

于 2013-09-23T01:41:43.823 に答える