Posso carregar um UIImage de um URL?

Eu tenho um URL para uma imagem (consegui-lo de UIImagePickerController), mas não tenho mais a imagem na memory (o URL foi salvo de uma execução anterior do aplicativo). Posso recarregar o UIImage a partir do URL novamente?

Eu vejo que UIImage tem um imageWithContentsOfFile: mas eu tenho um URL. Posso usar o dataWithContentsOfURL do NSData: para ler o URL?

EDIT1


com base na resposta do @ Daniel eu tentei o seguinte código, mas não funciona …

NSLog(@"%s %@", __PRETTY_FUNCTION__, photoURL); if (photoURL) { NSURL* aURL = [NSURL URLWithString:photoURL]; NSData* data = [[NSData alloc] initWithContentsOfURL:aURL]; self.photoImage = [UIImage imageWithData:data]; [data release]; } 

Quando eu corri, o console mostra:

 -[PhotoBox willMoveToWindow:] file://localhost/Users/gary/Library/Application%20Support/iPhone%20Simulator/3.2/Media/DCIM/100APPLE/IMG_0004.JPG *** -[NSURL length]: unrecognized selector sent to instance 0x536fbe0 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL length]: unrecognized selector sent to instance 0x536fbe0' 

Olhando para a pilha de chamadas, eu estou chamando URLWithString, que chama URLWithString: relativeToURL :, então initWithString: relativeToURL :, então _CFStringIsLegalURLString, então CFStringGetLength, em seguida, forwarding_prep_0 , então encaminhando , então – [NSObject doesNotRecognizeSelector].

Alguma idéia do porque meu NSString (o endereço do photoURL é 0x536fbe0) não responde ao comprimento? Por que diz que não responde a – [duração da NSURL]? Não sabe que param é um NSString, não um NSURL?

EDIT2


OK, o único problema com o código é a string para conversão de URL. Se eu codificar a string, tudo mais funciona bem. Então, algo está errado com o meu NSString e se eu não consigo descobrir, eu acho que isso deve ser uma questão diferente. Com esta linha inserida (eu colei o caminho do log do console acima), ele funciona bem:

 photoURL = @"file://localhost/Users/gary/Library/Application%20Support/iPhone%20Simulator/3.2/Media/DCIM/100APPLE/IMG_0004.JPG"; 

Você pode fazer isso dessa maneira (de forma síncrona, mas compacta):

 UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:MyURL]]]; 

Uma abordagem muito melhor é usar o LazyTableImages da Apple para preservar a interatividade.

Você pode experimentar o SDWebImage , ele fornece:

  1. Carregamento asynchronous
  2. Cache para uso offline
  3. Coloque a imagem do suporte para aparecer durante o carregamento
  4. Funciona bem com o UITableView

Exemplo rápido:

  [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; 

obtenha DLImageLoader e tente seguir o código

  [DLImageLoader loadImageFromURL:imageURL completed:^(NSError *error, NSData *imgData) { imageView.image = [UIImage imageWithData:imgData]; [imageView setContentMode:UIViewContentModeCenter]; }]; 

Outro exemplo típico do mundo real de usar o DLImageLoader, que pode ajudar alguém …

 PFObject *aFacebookUser = [self.fbFriends objectAtIndex:thisRow]; NSString *facebookImageURL = [NSString stringWithFormat: @"http://graph.facebook.com/%@/picture?type=large", [aFacebookUser objectForKey:@"id"] ]; __weak UIImageView *loadMe = self.userSmallAvatarImage; // ~~note~~ you my, but usually DO NOT, want a weak ref [DLImageLoader loadImageFromURL:facebookImageURL completed:^(NSError *error, NSData *imgData) { if ( loadMe == nil ) return; if (error == nil) { UIImage *image = [UIImage imageWithData:imgData]; image = [image ourImageScaler]; loadMe.image = image; } else { // an error when loading the image from the net } }]; 

Como eu mencionei acima outra grande biblioteca para considerar estes dias é Haneke (infelizmente não é tão leve).

E a versão rápida:

  let url = NSURL.URLWithString("http://live-wallpaper.net/iphone/img/app/i/p/iphone-4s-wallpapers-mobile-backgrounds-dark_2466f886de3472ef1fa968033f1da3e1_raw_1087fae1932cec8837695934b7eb1250_raw.jpg"); var err: NSError? var imageData :NSData = NSData.dataWithContentsOfURL(url,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err) var bgImage = UIImage(data:imageData) 

Experimente este código, você pode definir o carregamento de imagens com ele, para que os usuários saibam que seu aplicativo está carregando uma imagem do URL:

 UIImageView *yourImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"loading.png"]]; [yourImageView setContentMode:UIViewContentModeScaleAspectFit]; //Request image data from the URL: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://yourdomain.com/yourimg.png"]]; dispatch_async(dispatch_get_main_queue(), ^{ if (imgData) { //Load the data into an UIImage: UIImage *image = [UIImage imageWithData:imgData]; //Check if your image loaded successfully: if (image) { yourImageView.image = image; } else { //Failed to load the data into an UIImage: yourImageView.image = [UIImage imageNamed:@"no-data-image.png"]; } } else { //Failed to get the image data: yourImageView.image = [UIImage imageNamed:@"no-data-image.png"]; } }); }); 

Confira o AsyncImageView fornecido aqui . Um bom exemplo de código, e pode até ser usado corretamente “fora da checkbox” para você.

O AFNetworking fornece carregamento de imagem assíncrona para um UIImageView com suporte de espaço reservado. Ele também suporta redes assíncronas para trabalhar com APIs em geral.

Se você está realmente absolutamente certo de que a NSURL é uma URL de arquivo, ou seja, [url isFileURL] tem a garantia de retornar true no seu caso, então você pode simplesmente usar:

 [UIImage imageWithContentsOfFile:url.path] 

O caminho usando um Swift Extension para UIImageView (código fonte aqui ):

Criando Propriedade Computada para UIActivityIndicatorView Associada

 import Foundation import UIKit import ObjectiveC private var activityIndicatorAssociationKey: UInt8 = 0 extension UIImageView { //Associated Object as Computed Property var activityIndicator: UIActivityIndicatorView! { get { return objc_getAssociatedObject(self, &activityIndicatorAssociationKey) as? UIActivityIndicatorView } set(newValue) { objc_setAssociatedObject(self, &activityIndicatorAssociationKey, newValue, UInt(OBJC_ASSOCIATION_RETAIN)) } } private func ensureActivityIndicatorIsAnimating() { if (self.activityIndicator == nil) { self.activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray) self.activityIndicator.hidesWhenStopped = true let size = self.frame.size; self.activityIndicator.center = CGPoint(x: size.width/2, y: size.height/2); NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in self.addSubview(self.activityIndicator) self.activityIndicator.startAnimating() }) } } 

Inicializador e Setter personalizados

  convenience init(URL: NSURL, errorImage: UIImage? = nil) { self.init() self.setImageFromURL(URL) } func setImageFromURL(URL: NSURL, errorImage: UIImage? = nil) { self.ensureActivityIndicatorIsAnimating() let downloadTask = NSURLSession.sharedSession().dataTaskWithURL(URL) {(data, response, error) in if (error == nil) { NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in self.activityIndicator.stopAnimating() self.image = UIImage(data: data) }) } else { self.image = errorImage } } downloadTask.resume() } } 

Certifique-se de ativar essas configurações no iOS 9:

Configurações de segurança de transporte do aplicativo no Info.plist para garantir o carregamento da imagem do URL para permitir a imagem de download e defini-la.

insira a descrição da imagem aqui

E escreva este código:

 NSURL *url = [[NSURL alloc]initWithString:@"https://www.google.co.in/"]; NSData *data =[NSData dataWithContentsOfURL:url]; quickViewImage.image = [UIImage imageWithData:data];