iphone - from - picasso for swift
¿Qué sucede con SDWebImage Cached Images en mi aplicación cuando cambia el archivo de imagen en el servidor? (10)
Estoy usando la biblioteca SDWebImage
para almacenar en caché imágenes web en mi aplicación:
https://github.com/rs/SDWebImage/blob/master/README.md
Uso actual:
[imageView setImageWithURL:[NSURL URLWithString:profilePictureUrl] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
Mi pregunta es ¿qué sucede una vez que la imagen ha sido almacenada en la memoria caché y luego un par de días más tarde ese archivo de imagen en el servidor se ha actualizado con una nueva imagen?
Por el momento, mi aplicación sigue mostrando la imagen en caché.
No puedo ver en ninguno de los documentos sobre cómo configurar un tiempo de espera de caché o algo que reconozca que el tamaño del archivo ha cambiado.
Si alguien tiene experiencia en el uso de esta biblioteca en particular, cualquier ayuda sería muy apreciada.
Gracias por adelantado.
Eché un vistazo al código fuente. Procesa el método setImageWithURL
la setImageWithURL
manera:
- Pregúntele a la memoria caché si la imagen está allí, si es así devuelva la imagen y no continúe
- Pregúntale a la memoria caché de disco si la imagen está allí, si la respuesta es sí, devuelve la imagen y no vayas más allá
- Intente descargar la imagen, devuelva la imagen en caso de éxito, de lo contrario, mantenga la imagen de marcador de posición
No se envía ninguna solicitud para preguntar al servidor remoto si hay una versión nueva mientras hay algo viejo en el disco, como usar ETags del protocolo HTTP.
Profundizando un poco más, el tiempo de caché se establece en un valor estático en SDImageCache.m
static NSInteger cacheMaxCacheAge = 60*60*24*7; // 1 week
no puede ser cambiado con un setter.
Por lo tanto, siempre que la imagen en la memoria caché sea válida, la lib SDWebImage
no descargará nada nuevo. Después de una semana, descargará su imagen modificada.
El problema con el envejecimiento de SDImageCache (que ahora tiene un setter: maxCacheAge) es que SDWebImage nunca hace nada proactivamente con él. Necesita invocar CleanDisk usted mismo en algún momento para purgar los datos antiguos de la memoria caché. Nota: SDWebImage invoca CleanDisk cuando la aplicación finaliza, pero no se garantiza que las aplicaciones reciban una notificación de finalización del sistema operativo.
En caso de que desee cambiar la duración de la memoria caché predeterminada en Swift. Establezca esto en su AppDelegate.
Versión 3:
SDWebImageManager.sharedManager().imageCache.maxCacheAge = CACHE_TIME_IN_SECONDS
Versión 4:
SDWebImageManager.shared().imageCache?.config.maxCacheAge = CACHE_TIME_IN_SECONDS
-
Creo que esto solo afecta a las imágenes que son cachés después de establecer este valor. Es decir, si su aplicación almacena en caché una imagen con la caducidad del caché predeterminada y luego lo cambia de otra forma, sus imágenes solo caducarán después de una semana. Una solución fácil para esto es simplemente limpiar su caché.
Flujo SDWebImage:
1) SDWebImage
almacena en caché la imagen recuperada del servidor
2) SDWebImage
usa la URL es la clave para obtener la imagen de la memoria caché
3) verificaciones de SDWebImage
:
si es capaz de obtener la imagen de la memoria caché - OK
si no (por ejemplo, se cambió la url) - no se puede obtener la imagen de la memoria caché
así que, en realidad, obtendrá ImageView (s) SDWebImage
y SDWebImage
debe recuperar imágenes del servidor de nuevo
Las últimas Swift 3.0 * y SDWebImage
SDWebImageManager.shared().imageCache?.deleteOldFiles(completionBlock: nil)
Mientras leo en el archivo Léame de SDWeb en git, podría ayudar:
En su caso, puede usar el indicador SDWebImageRefreshCached
. Esto degradará ligeramente el rendimiento, pero respetará los encabezados de control de caché HTTP:
[imageView sd_setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/olivier.poitrey/picture"]
placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
options:SDWebImageRefreshCached];
Puede usar el parámetro de options
.
Versión Swift:
imageView.sd_setImage(with: URL(string: URLWithString:profilePictureUrl),
placeholderImage: UIImage(named: "placeholder"),
options: .refreshCached,
completed: nil)
Versión Objective-C:
[imageView sd_setImageWithURL:[NSURL URLWithString:profilePictureUrl]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
options:SDWebImageRefreshCached
completed: nil];
¡Aclamaciones!
SDWebImage hace un caché agresivo por defecto. Pero ahora le dan la opción de respetar sus encabezados de control de caché HTTP y obtener la última imagen.
Para esto tienen un nuevo método donde en opciones puedes pasar SDWebImageRefreshCached
[imageView sd_setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/xyz/picture"]
placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
options:SDWebImageRefreshCached];
Puede encontrar los detalles completos del método y la explicación here .
Debajo está lo que he observado.
Si el nombre / ruta de la imagen es el mismo, SDWebImage no lo descargará nuevamente durante 1 semana.
Independientemente del nombre de la imagen, SDWebImage volverá a descargar la imagen después de 1 semana (desde el momento en que se descargó).
static NSInteger cacheMaxCacheAge = 60*60*24*7; // 1 week
Tienen una base de datos donde se almacenan todas las imágenes URL. Para ellos, la URL de la imagen es como la clave principal (clave única).
Entonces, básicamente, lo que hacen es si la URL se cambia y no está presente en DB, descárguelo.
Desde mi punto de vista, lo que están haciendo es DERECHO. Ex. Si carga una imagen, digamos que para el usuario A, el nombre de la imagen debe cambiarse y esto es básico. Sé que algunos desarrolladores prefieren que el nombre de la imagen sea el mismo (como userA.png siempre).
NSURL *imageUrl = nil;
NSDate *lastUpdate = [[NSUserDefaults standardUserDefaults] objectForKey:@"lastUpdate"];
NSDate *currentDate = [NSDate date];
if (lastUpdate == nil
|| ![lastUpdate isKindOfClass:[NSDate class]]
|| [currentDate timeIntervalSinceDate:lastUpdate] > 60 * 60 *24) {
[[NSUserDefaults standardUserDefaults] setObject:currentDate forKey:@"lastUpdate"];
NSString *urlString = [NSString stringWithFormat:@"http://yourdomain.com/image/image.png?%f", [currentDate timeIntervalSince1970]];
imageUrl = [NSURL URLWithString:urlString];
}