Descargar y guardar archivos grandes con RestKit

Estoy usando RestKit para descargar varios archivos en mi aplicación. Siempre que los archivos no sean demasiado grandes, todo funciona a la perfección. Desafortunadamente, intenté descargar un archivo de video grande (alrededor de 230 MB) y obtuve un memory warning y la aplicación falla.

Comienzo la descarga con la siguiente linea

[[RKClient sharedClient] get:[NSString stringWithFormat:@"/%@", listItem.filename] delegate:self];

En el método de delegado lo guardo localmente en appDirectory/Library/Caches/

- (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response
{
    NSURL * url = [NSURL fileURLWithPath:[cacheDirectory stringByAppendingPathComponent:response.URL.lastPathComponent]];

    [[response body] writeToURL:url atomically:YES];
}

Revisé la aplicación en Instruments en busca de pérdidas de memoria y vi que Live Bytes para *Overall Allocations* siguió levantándose ante el Low Memory Alerts vino alrededor 100 MB. Aunque no hubo filtraciones.

Eliminando la línea responsable de guardar el archivo ([[response body] writeToURL:url atomically:YES];) no cambió nada, así que supongo que el problema está en algún lugar de RestKit.

Mientras investigaba me topé con un método de ASIHTTPRequest que permite la descarga directa de archivos y pensó que algo así podría resolver el problema, aunque no estoy seguro.

¿Existe la posibilidad en RestKit para la descarga directa que me perdí?

or

¿Hay alguna forma mejor de descargar archivos con RestKit que deba conocer?

preguntado el 22 de mayo de 12 a las 16:05

1 Respuestas

Encontré el mismo problema, desafortunadamente no creo que haya otra forma de evitarlo que no sea modificar su copia local de RestKit. El problema se encuentra en - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data, exactamente en [_body appendData:data];. Como puede ver, RestKit mantiene el cuerpo de la respuesta en la memoria y agrega los bytes a medida que se envían desde el servidor. Esta es la razón por la que recibe advertencias de poca memoria. Mi solución fue agregar una propiedad a RKRequest y escribir datos directamente en el sistema de archivos dependiendo de si la solicitud es una solicitud de archivo grande o no:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if ([_request dontKeepBytesInMemory]) {
    if ([[_request delegate] respondsToSelector:@selector(request:didReceivedData:totalBytesExectedToReceive:)]) {
        [[_request delegate] request:_request didReceivedData:data totalBytesExectedToReceive:_httpURLResponse.expectedContentLength];
    }
} else {
    [_body appendData:data];
    if ([[_request delegate] respondsToSelector:@selector(request:didReceivedData:totalBytesReceived:totalBytesExectedToReceive:)]) {
        [[_request delegate] request:_request didReceivedData:[data length] totalBytesReceived:[_body length] totalBytesExectedToReceive:_httpURLResponse.expectedContentLength];
    }
}

}

También necesitaba un método de delegado RKRequest adicional en el protocolo, para poder procesar las grandes respuestas por separado. El método de delegado original define totalBytesReceived que es simplemente el [_body length], pero si escribe bytes directamente en el sistema de archivos, puede verificar el tamaño del archivo actual para rastrear el estado de la descarga. Si está buscando una buena manera de guardar bytes directamente en el sistema de archivos, eche un vistazo a la clase NSFileHandle: admite el desplazamiento de archivos, por lo que puede arrojar cualquier NSData y lo agregará automáticamente.

contestado el 22 de mayo de 12 a las 16:05

Oye, gracias por la respuesta. Todavía no he tenido tiempo de investigar esto, pero parece legítimo. Es de esperar que vuelva pronto y dé su opinión en caso de que haya un problema... - incauto

¿Puedes compartir tu código? Estoy muy interesado en descargar archivos grandes con restkit... - fvisticot

Desafortunadamente, no tengo acceso al código ahora (cambié de empleador), pero me complacerá guiarlo si me dice dónde está exactamente atrapado. - Lawicko

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.