iOS AFNetworking downloadProgressBlock cálculo que devuelve numbers negativos

Estoy usando AFNetworking para download datos que se analizan con una class de terceros. He usado AFNetworking para hacer acciones similares muchas veces antes, pero por alguna razón, cuando llamo a downloadProgressBlock y hago el cálculo para usar con mi barra de progreso, los numbers regresan negativos. Vea abajo:

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 

A continuación se muestra mi código:

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

Sospecho que encontrará que el problema es totalBytesExpectedToRead . Específicamente, esto proviene de la propiedad NSURLResponse , expectedContentLength , que como dicen los docs :

Valor de retorno

La longitud de contenido esperada del receptor, o NSURLResponseUnknownLength si la longitud no se puede determinar.

Discusión

Algunas implementaciones de protocolo informan la longitud del contenido como parte de la respuesta, pero no todos los protocolos garantizan la entrega de esa cantidad de datos. Los clientes deben estar preparados para manejar más o less datos.

Por cierto, esta constante, NSURLResponseUnknownLength , es igual a -1, lo que explicaría tus valores calculados. Esta es la forma en que el sistema le informa que no pudo determinar la duración de la respuesta.

Entonces, en el peor de los casos, obtendrá -1 como una cantidad de bytes esperada. Incluso si no es -1, no es completamente confiable (especialmente un problema si ha escrito su propio código de server). Tu aplicación debe manejar con gracia cualquier contenido expectedContentLength ContentContength a tu aplicación. La mayoría de las veces, si obtiene un valor no negativo, generalmente obtiene un valor que se puede usar efectivamente para un cálculo de "porcentaje completo", pero no confíe en él (por ejemplo, puede recibir más bytes o less bytes de expectedContentLength informes expectedContentLength ). Maneja agraciado valores excepcionales.

Por ejemplo, al configurar mi barra de progreso, he hecho algo como:

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

Esto me da una barra de progreso que progresa lentamente al 100% a medida que avanza la descarga si tengo un buen valor de longitud de contenido esperado, pero de lo contrario me muestra una barra de progreso que progresa del 0% al 100% por cada 1,000,000 bytes descargados. Este último escenario no es ideal, pero no hay mucho que pueda hacer a less que su server informe una longitud de contenido esperada precisa.

De forma alternativa, si nunca obtienes un expectedContentLength confiable, puedes optar por usar una vista de progreso indeterminada (por ejemplo, UIActivityIndicatorView ) que evita por completo este problema.

En pocas palabras, el cálculo exitoso del progreso depende de que su server brinde un valor legítimo para los bytes esperados. Si observa totalBytesExpectedToRead , apuesto a que obtendrá -1 y verá como resultado sus curiosos valores de porcentaje de progreso calculados.