iOS: descarga la image desde la url y guarda en el dispositivo

Estoy intentando download la image de la url http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg

Estoy usando el siguiente código, pero la image no se guarda en el dispositivo. Quiero saber qué estoy haciendo mal.

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg"]]; [NSURLConnection connectionWithRequest:request delegate:self]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"pkm.jpg"]; NSData *thedata = NULL; [thedata writeToFile:localFilePath atomically:YES]; UIImage *img = [[UIImage alloc] initWithData:thedata]; 

Si configura theData a nil , ¿qué esperas que escriba en el disco?

Lo que puede usar es NSData* theData = [NSData dataWithContentsOfURL:yourURLHere]; para cargar los datos del disco y luego savelo usando writeToFile:atomically: Si necesita más control sobre el process de carga o si lo tiene en segundo plano, consulte la documentation de NSURLConnection y la guía asociada.

Sucede que tengo exactamente lo que buscas.

Obtener image de la URL

 -(UIImage *) getImageFromURL:(NSString *)fileURL { UIImage * result; NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; result = [UIImage imageWithData:data]; return result; } 

Guardar image

 -(void) saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath { if ([[extension lowercaseString] isEqualToString:@"png"]) { [UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]] options:NSAtomicWrite error:nil]; } else if ([[extension lowercaseString] isEqualToString:@"jpg"] || [[extension lowercaseString] isEqualToString:@"jpeg"]) { [UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]] options:NSAtomicWrite error:nil]; } else { NSLog(@"Image Save Failed\nExtension: (%@) is not recognized, use (PNG/JPG)", extension); } } 

Cargar image

 -(UIImage *) loadImage:(NSString *)fileName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath { UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.%@", directoryPath, fileName, extension]]; return result; } 

Cómo

 //Definitions NSString * documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; //Get Image From URL UIImage * imageFromURL = [self getImageFromURL:@"http://www.yourdomain.com/yourImage.png"]; //Save Image to Directory [self saveImage:imageFromURL withFileName:@"My Image" ofType:@"png" inDirectory:documentsDirectoryPath]; //Load Image From Directory UIImage * imageFromWeb = [self loadImage:@"My Image" ofType:@"png" inDirectory:documentsDirectoryPath]; 

Este es el código para download la image de la url y save esa image en el dispositivo y este es el enlace de reference.

  NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg"]]; [NSURLConnection connectionWithRequest:request delegate:self]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"pkm.jpg"]; NSData *thedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg"]]; [thedata writeToFile:localFilePath atomically:YES]; 

Obtener image de la URL

 -(UIImage *) getImageFromURL:(NSString *)fileURL { UIImage * result; NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; result = [UIImage imageWithData:data]; return result; } 

Esto funcionó muy bien para mí, pero encontré problemas de memory con CFData (tienda). Se solucionó con un autoreleasepool:

  -(UIImage *) getImageFromURL:(NSString *)fileURL { @autoreleasepool { UIImage * result; NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; result = [UIImage imageWithData:data]; return result; } } 

Ya que estamos en IOS6 ahora, ya no necesita escribir imágenes en el disco necesariamente.
Desde iOS5 ahora puede configurar "permitir almacenamiento externo" en un atributo binary conetworkingata. Según las notas de lanzamiento de las manzanas significa lo siguiente:

Los pequeños valores de datos, como las imágenes en miniatura, se pueden almacenar de manera eficiente en una database, pero el sistema de files gestiona directamente las fotografías de gran tamaño u otros medios. Ahora puede especificar que el valor de un atributo de object gestionado se pueda almacenar como un logging externo; consulte setAllowsExternalBinaryDataStorage: cuando está habilitado, Core Data decide de forma heurística por valor si debe save los datos directamente en la database o almacenar un URI a un file separado que administra para usted. No puede consultar en function del contenido de una propiedad de datos binarys si utiliza esta opción.

Hola, está claro que estás escribiendo datos NULL en tu file.

En su statement de código NSData * thedata = NULL; indica que asigna valor NULL a sus datos.

También está escribiendo datos NULL en su file.

Revise su código una vez más.

 -(IBAction)BtnDwn:(id)sender { [self.actvityIndicator startAnimating]; NSURL *URL = [NSURL URLWithString:self.dataaArray]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURLSession *session = [NSURLSession shanetworkingSession]; NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) { NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSURL *documentsDirectoryURL = [NSURL fileURLWithPath:documentsPath]; NSURL *documentURL = [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]]; BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:[documentURL path]]; if (exists) { NSLog(@"not created"); UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Download" message:@"sory,file already exists" delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles:nil]; [alert show]; } else { [[NSFileManager defaultManager] moveItemAtURL:location toURL:documentURL error:nil]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Download" message:@"Succesfully downloaded" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [self.actvityIndicator stopAnimating]; NSLog(@"wait downloading......"); [alert show]; } }]; [downloadTask resume]; } 

Aquí hay un ejemplo de cómo descargo banners a mi aplicación. Descargo las imágenes en segundo plano, y la mayoría de mis aplicaciones no utilizan el recuento de references, por lo que libero objects.

 - (void)viewDidLoad { [super viewDidLoad]; [NSThread detachNewThreadSelector:@selector(loadImageInBackground) toTarget:self withObject:nil]; } - (void) loadImageInBackground { NSURL *url = [[NSURL alloc] initWithString:@"http://yourImagePath.png"]; NSData *data = [[NSData alloc] initWithContentsOfURL:url]; [url release]; UIImage *result = [[UIImage alloc] initWithData:data]; [data release]; UIImageView *banner_ImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)]; [self.view addSubview:banner_ImageView]; banner_ImageView.image = result; [result release]; } 

A continuación, le indicamos cómo puede save una image de forma asíncrona en Swift:

 requestImage("http://www.asdf.com/89asdf.gif") { (image) -> Void in let myImage = image } func requestImage(url: String, success: (UIImage?) -> Void) { requestURL(url, success: { (data) -> Void in if let d = data { success(UIImage(data: d)) } }) } func requestURL(url: String, success: (NSData?) -> Void, error: ((NSError) -> Void)? = nil) { NSURLConnection.sendAsynchronousRequest( NSURLRequest(URL: NSURL (string: url)!), queue: NSOperationQueue.mainQueue(), completionHandler: { response, data, err in if let e = err { error?(e) } else { success(data) } }) } 

Está incluido como una function estándar en mi repository:

https://github.com/goktugyil/EZSwiftExtensions