iOS:从url下载图片并保存在设备中

我正在尝试从url下载图片http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg

我正在使用下面的代码,但图像不保存在设备中。 我想知道我做错了什么。

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]; 

如果你设置的theData nil ,你期望它写入磁盘?

你可以使用的是NSData* theData = [NSData dataWithContentsOfURL:yourURLHere]; 从磁盘加载数据,然后使用writeToFile:atomically:保存writeToFile:atomically: 如果您需要更多的控制加载过程或在后台使用,请查看NSURLConnection的文档和相关指南。

我恰好有你正在寻找的东西。

从URL获取图像

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

保存图片

 -(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); } } 

加载图像

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

如何

 //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]; 

这是从url下载图像并将该图像保存在设备中的代码, 这是参考链接。

  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]; 

从URL获取图像

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

这对我很好,但我碰到CFData(存储)的内存问题。 用autoreleasepool修复它:

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

由于我们现在正在使用IOS6,因此不再需要将映像写入磁盘。
自iOS5以来,您现在可以在coredata二进制属性上设置“允许外部存储”。 根据苹果发行说明,这意味着以下内容:

像图像缩略图这样的小数据值可以高效地存储在数据库中,但大图片或其他媒体最好由文件系统直接处理。 您现在可以指定被pipe理对象属性的值可以作为外部logging存储 – 请参阅setAllowsExternalBinaryDataStorage:启用时,核心数据试探性地决定是否应将数据直接保存在数据库中或存储URI到一个单独的文件,它为你pipe理。 如果使用此选项,则无法基于二进制数据属性的内容进行查询。

嗨很明显,你正在写NULL数据到你的文件。

在你的代码语句NSData * thedata = NULL; 表示您为您的数据分配NULL值。

您正在为您的文件写入NULL数据。

请再次检查您的代码。

 -(IBAction)BtnDwn:(id)sender { [self.actvityIndicator startAnimating]; NSURL *URL = [NSURL URLWithString:self.dataaArray]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURLSession *session = [NSURLSession sharedSession]; 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]; } 

这里是我如何下载横幅到我的应用程序的例子。 我在后台下载图像,而我的大多数应用程序不使用引用计数,因此我释放对象。

 - (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]; } 

以下是如何在Swift中asynchronous保存图像:

 requestImage("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) } }) } 

它包含在我的回购标准function:

https://github.com/goktugyil/EZSwiftExtensions