:::: MENU ::::

Carga de imagen asíncrona UIImageView en aplicación iOS (iPhone, iPad)

4.33 avg. rating (83% score) - 6 votes

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




5 Comments

  • Responder puppetboo |

    Hola, saludos mi buen, me gusto tu tutorial, queria preguntarte como podria hacer eso mismo para una imagen quedebe ser asignada como background a botones dinamicos en otra vista, como es posible desde la clase UIImageViewAsync devolver un objeto de tipo UIImage cuando este yaa este creado? de antemano gracias :)

    • Responder Daniel |

      Puppetboo, si lo que necesitas es cambiar la imagen de un botón, entonces lo que deberías hacer es derivar la clase UIButton, en lugar de la clase UIImageView.
      El resto del tutorial te sirve igual. Sólo al final del proceso, en el método connectionDidFinishLoading, en lugar de asignar la imagen al UIImageView, la asignas al botón con:
      [boton setImage:[UIImage imageWithData:imageData] forState:UIControlStateNormal]­;

  • Responder Richard |

    Muchas Gracias por este Video-Tutorial, me ha sido de grandisima utilidad ;)
    Esta muy bien explicado y es de muchisima utilidad la clase UIImageViewAsync que has realizado
    SL2

Hey! Qué opinas sobre el artículo?