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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2499176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:02:31  来源:igfitidea点击:

iOS: Download image from url and save in device

iphoneiosimagecocoa-touchipad

提问by User97693321

I am trying to download the image from the url http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg

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

I am using the following code, but image is not saved in the device. I want to know what I am doing wrong.

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

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

采纳答案by Alfonso

If you set theDatato nil, what do you expect it to write to the disk?

如果您设置theDatanil,您希望它写入磁盘的内容是什么?

What you can use is NSData* theData = [NSData dataWithContentsOfURL:yourURLHere];to load the data from the disk and then save it using writeToFile:atomically:. If you need more control over the loading process or have it in background, look at the documentation of NSURLConnectionand the associated guide.

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

回答by Fernando Cervantes

I happen to have exactly what you are looking for.

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

Get Image From URL

从 URL 获取图像

-(UIImage *) getImageFromURL:(NSString *)fileURL {
    UIImage * result;

    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
    result = [UIImage imageWithData:data];

    return result;
}

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

Load Image

加载图片

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

    return result;
}

How-To

如何

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

回答by User97693321

This is the code to download the image from url and save that image in the device and thisis the reference link.

这是从 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];

回答by mark.ed

Get Image From URL

-(UIImage *) getImageFromURL:(NSString *)fileURL {
    UIImage * result;

    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
    result = [UIImage imageWithData:data];

    return result;
}

从 URL 获取图像

-(UIImage *) getImageFromURL:(NSString *)fileURL {
    UIImage * result;

    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
    result = [UIImage imageWithData:data];

    return result;
}

This worked great for me but I ran into memory issues with CFData (store). Fixed it with an autoreleasepool:

这对我很有用,但我遇到了 CFData(存储)的内存问题。使用自动释放池修复它:

 -(UIImage *) getImageFromURL:(NSString *)fileURL {
    @autoreleasepool {
     UIImage * result;

     NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
     result = [UIImage imageWithData:data];

     return result;
    }
 }

回答by Rahul Ranjan

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

回答by Esqarrouth

Here is how you can save an image asynchronously in Swift:

以下是在 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)
            }
    })
}

Its included as a standard function in my repo:

它作为标准函数包含在我的 repo 中:

https://github.com/goktugyil/EZSwiftExtensions

https://github.com/goktugyil/EZSwiftExtensions

回答by Jim

Hi It is clear that you are writing NULL data to your file.

嗨 很明显,您正在将 NULL 数据写入文件。

In your code statement NSData *thedata = NULL; indicates that you assign NULL value to your data.

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

You are writing NULL data to your file as well.

您也在将 NULL 数据写入文件。

Please check your code once again.

请再次检查您的代码。

回答by Alexander

Since we are on IOS6 now, you no longer need to write images to disk neccessarily.
Since iOS5 you are now able to set "allow external storage" on an coredata binary attribute. According to apples release notes it means the following:

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

Small data values like image thumbnails may be efficiently stored in a database, but laarge photos or other media are best handled directly by the file system. You can now specify that the value of a managed object attribute may be stored as an external record - see setAllowsExternalBinaryDataStorage:When enabled, Core Data heuristically decides on a per-value basis if it should save the data directly in the database or store a URI to a separate file which it manages for you. You cannot query based on the contents of a binary data property if you use this option.

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

回答by Bobby

Here's an example of how I download banners to my app. I download the images in the background, and most of my apps do not use reference counting so I release 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];
}