iOS: Download image from url and save in device

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.

  • plist file not being found
  • Where to store global constants in an iOS application?
  • How can I make deleteRowsAtIndexPaths: work with GenericTableViewController?
  • Core data find-or-create most efficient way
  • Keeping the order of NSDictionary keys when converted to NSData with
  • How to get indexPath.row of tableView which is currently being displayed?
  •  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];
    

    9 Solutions Collect From Internet About “iOS: Download image from url and save in device”

    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.

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

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

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

    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.

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

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

    You are writing NULL data to your file as well.

    Please check your code once again.

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

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

    Here is how you can save an image asynchronously in 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:

    https://github.com/goktugyil/EZSwiftExtensions