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: