Carga de imagen asíncrona UIImageView en aplicación iOS (iPhone, iPad)
5 votos, 4.40 media (87% puntos)

En el siguiente vídeo podéis ver cómo descargar imágenes desde una URL de forma asíncrona y asignarlas a un control UIImageView.

La carga de imágenes asíncrona debería hacerse siempre que se necesite utilizar imágenes descargadas de un servicio o servidor Web, por ejemplo en aplicaciones tipo red social, donde se deben mostrar imágenes subidas por otros usuarios, etc.

Si la carga de las imágenes no se realiza de forma asíncrona, el interfaz de usuario de la aplicación se bloquea durante la descarga de datos, lo que proporciona una mala experiencia de usuario. Si los bloqueos del interfaz de usuario de nuestra aplicación iOS son frecuentes, podría ser rechazada por Apple para la publicación en la AppStore.

En el vídeo se explica como implementar una subclase de UIImageView que tenga la funcionalidad de descarga de datos asíncrona desde una URL. Para ello, se utiliza una conexión asíncrona NSURLConnection y se implementa el protocolo NSURLConnectionDelegate.

La subclase creada puede utilizarse tanto desde Interface Builder como desde el código de la aplicación y se puede re-utilizar en posteriores aplicaciones iOS.

Si no queréis crear una clase nueva y sólo necesitáis de forma puntual, podéis echar un vistazo aquí:

La subclase de UIImageView, queda como sigue:

UIImageViewAsync.h

#import <UIKit/UIKit.h>

@interface UIImageViewAsync : UIImageView<NSURLConnectionDelegate> {
    
    NSURLConnection *imageConnection;
    NSMutableData *imageData;
}

-(void)loadFromUrl:(NSString*)url;

UIImageViewAsync.c

#import "UIImageViewAsync.h"

@implementation UIImageViewAsync


-(void)loadFromUrl:(NSString*)url {
        
    // Datos de la imagen descargada
    imageData = [[NSMutableData alloc] init];

    // Creamos la URL
    NSURL* urlImage = [NSURL URLWithString:url];
    
    // Creamos la conexión de datos
    NSURLRequest *request = [NSURLRequest requestWithURL:urlImage 
                                             cachePolicy:NSURLCacheStorageNotAllowed 
                                         timeoutInterval:30.0];
    
    // Lanzamos la conexión
    imageConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

/**
 *  Recepción de datos asíncrona
 */
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [imageData appendData:data];
}

/**
 *  La conexión finaliza con error; imagen no descargada
 */
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    imageData = nil;
    imageConnection = nil;
}

/**
 *  Conexión finaliza con éxito; imagen descargada
 */
-(void)connectionDidFinishLoading:(NSURLConnection*)connection {

    [self setImage:[UIImage imageWithData:imageData]];
     imageData = nil;
     imageConnection = nil;
}

@end