iOS: Download image from url and save in device

90,358

Solution 1

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

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 NSURLConnection and the associated guide.

Solution 2

I happen to have exactly what you are looking for.

Get Image From 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];

Solution 3

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

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

Solution 4

Get Image From 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:

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

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

     return result;
    }
 }

Solution 5

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:

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.

Share:
90,358

Related videos on Youtube

User97693321
Author by

User97693321

Passionate for mobile application development.

Updated on December 02, 2020

Comments

  • User97693321
    User97693321 over 3 years

    I am trying to download the image from the 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];
    
    • Jasarien
      Jasarien about 14 years
      Why the heck are you doing this: NSData *thedata = NULL;?
    • Jayprakash Dubey
      Jayprakash Dubey over 9 years
    • quemeful
      quemeful almost 8 years
      @Jasarien because he's asking a question... lol
  • Alfonso
    Alfonso about 14 years
    Note that sending a selector to nil does not have any effect, so actually nothing is written to disk (not even null data). Does not really matter in this case, but just to point out the subtle difference.
  • SaltyNuts
    SaltyNuts over 11 years
    If you are downloading an image with the expectation of saving it locally and not just displaying it, it would probably be better to create the file using [data writeToFile:options:error:] right away, instead of saving it in a UIImage object first. That way you will avoid re-compressing the image and losing all of EXIF data in the process.
  • SaltyNuts
    SaltyNuts over 11 years
    Why are you doing an asynchronous call with NSURLConnection and then following it up with a synchronous call to [NSData dataWithContentsOfURL...]? The NSURLConnection portion is just left hanging, doing nothing - but it will still pull data from the network, discarding it afterwards.
  • Gajendra K Chauhan
    Gajendra K Chauhan over 10 years
    @user97693321. How can I add multiple images parsed from web service?
  • Fernando Cervantes
    Fernando Cervantes over 10 years
    If you like my code, feel free to download my open source project Atom, which includes the above methods and many more. (github.com/fer94/atom)
  • m177312
    m177312 over 8 years
    Do not use getImageFromURL for downloading large images as It may block the main thread, causing unresponsive UI. Use an alternative which downloads the image on a background thread. More on developer.apple.com/library/mac/documentation/Cocoa/Conceptu‌​al/…
  • Trung Bui
    Trung Bui over 8 years
    This does exactly what I want. If you want to download image and save it locally, this worth a try.