2008-11-23 19 views
24

Estoy tratando de integrar un objeto NSURLConnection con UIProgressView, por lo que puedo actualizar al usuario mientras se está descargando un archivo en segundo plano.¿Cómo integrar NSURLConnection con UIProgressView?

Creé un objeto por separado para descargar el archivo en segundo plano, y estoy teniendo problemas para averiguar cómo actualizar la propiedad de progreso en el objeto UIProgressView con el valor correcto. Probablemente sea algo muy simple, pero no puedo resolverlo con Google.

Aquí está el código que tengo:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    [self.resourceData setLength:0]; 
    self.filesize = [NSNumber numberWithLongLong:[response expectedContentLength]]; 
    NSLog(@"content-length: %d bytes", self.filesize); 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [self.resourceData appendData:data]; 

    NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[self.resourceData length]]; 
    NSLog(@"resourceData length: %d", [resourceLength intValue]); 
    NSLog(@"filesize: %d", self.filesize); 
    NSLog(@"float filesize: %f", [self.filesize floatValue]); 
    progressView.progress = [resourceLength floatValue]/[self.filesize floatValue]; 
    NSLog(@"progress: %f", [resourceLength floatValue]/[self.filesize floatValue]); 
} 

Como se puede ver, la variable miembro resourceData mantiene los datos del archivo, ya que está siendo descargado. La variable de miembro del tamaño de archivo contiene el tamaño completo del archivo, tal como lo devuelve mi servicio web en su encabezado Content-Length.

Todo funciona bien, sigo obteniendo los datos descargados con múltiples ejecuciones de didReceiveData como debería, pero cuando trato de calcular el valor de progreso, no se devuelve el valor adecuado. Vea a continuación una pequeña muestra de lo que me pasa en mi registro de la consola:

content-length: 4687472 bytes 
resourceData length: 2904616 
filesize: 4687472 
float filesize: -1.000000 
progress: -2904616.000000 

Como referencia, progressView.progress es un flotador. tamaño de archivo es un NSNumber que contiene una longitud larga. Finalmente, resourceLength es un NSNumber que contiene un NSUInteger.

¿Qué me falta aquí?

+0

¿Qué se registra en la consola cuando ejecuta esto? ¿Están los campos de progreso correctamente impresos? –

+0

Ben, acaba de agregar una muestra del registro de la consola. – jpm

Respuesta

29

No estoy seguro de lo que me falta aquí, pero su filesize siendo -1 parece ser su problema. El API docs indica claramente que expectedContentLength puede no estar disponible y que se devuelve NSURLResponseUnknownLength en estos casos. NSURLResponseUnknownLength se define como:

#define NSURLResponseUnknownLength ((long long)-1) 

En estos casos, no se puede conseguir un progreso precisa. Tendrá que manejar esto y mostrar un medidor de progreso indeterminado de algún tipo.

+0

Dave, gracias por la respuesta. Agregué una llamada NSLog() adicional para ilustrar mi punto aún más. Agregué un enunciado de depuración que registraba "content-length" arriba. – jpm

+0

Supongo que no entiendo la pregunta, entonces ... ¿qué estás preguntando exactamente? –

+0

Pregunto: ¿qué me estoy perdiendo? ¿Por qué [self.filesize floatValue] devuelve -1 en lugar del valor de flotación real de su objeto NSNumber (que representa una longitud larga)? ¿Por qué el cálculo de división está completamente roto así? – jpm

6

Creo que está imprimiendo mal el tamaño del archivo. Si self.filesize es de hecho una NSNumber, lo imprima utilizando el formato %@, porque es un objeto, no una primitiva:

NSLog(@"filesize: %@", self.filesize); 

Al utilizar el %d, su son sólo la impresión de la puntero del valor de self.filesize . Para imprimir el valor de largo tiempo real, utilice %lli (%d es sólo para valores de 32 bits):

NSLog(@"filesize: %lli", [self.filesize longLongValue]); 

Así que su self.filesize es en realidad -1 y la división es correcta.

+0

Dave, justo lo suficiente en el error NSLog(). Sin embargo, lo que realmente quiero hacer es calcular un valor flotante (de 2 objetos NSNumber) para asignar a progressView.progress. Como puede ver arriba, no obtengo el valor esperado cuando hago una división simple. – jpm

+1

¡Lo estás haciendo bien! 2904616/-1 = -2904616 –

+1

Más específicamente 2904616/NSURLResponseUnknownLength = -2904616 –

0

En su código, el tamaño del archivo parece ser un objeto NSNumber (!).Así

NSLog(@"filesize: %d", self.filesize);

y

NSLog(@"content-length: %d bytes", self.filesize);

es probable que reportar algo así como la dirección (ID) de ese objeto (o algo más). Esta es la

filesize: 4687472

ves. Como se ha señalado por otros, el tamaño de archivo devuelto por la respuesta es, en efecto -1, es decir,

NSURLResponseUnknownLength

es decir, el servidor no arrojó el tamaño del archivo.