0

I'm downloading an image and then displaying it with UIImageView. Using this approach the image is downloaded every time the view is loaded. How would I go about storing it locally to avoid an unnecessary server request?

   [self requestData ] ;
   UIImage *userImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:userProfileImageUrl ]]] ;
   [self.profileImageView  setImage:userImage ] ;
Shaik Riyaz
  • 11,204
  • 7
  • 53
  • 70
hanumanDev
  • 6,592
  • 11
  • 82
  • 146
  • Well you just save it to the document directory with a name that you can derive from the URL. Then before loading it from the URL try if the image is in the document directory. If so load it from there and not from the URL. An other options is to increase the size of `NSURLCache` to make it store the image fro a longer time. Just be sure that the server then set the correct expire date on the image request. – rckoenes Nov 11 '13 at 12:15
  • I think you should use the `NSCache` to store image in the cache. [example](http://stackoverflow.com/questions/19216721/how-will-i-stop-repeating-the-loading-of-images-in-my-table-view/19217904#19217904) – MD. Nov 13 '13 at 11:58

4 Answers4

1

I would suggest using a library like SDWebImage that handles caching and asynchronous download.

Fr4ncis
  • 1,387
  • 1
  • 11
  • 23
1

Very first time, you have to save the image into NSDocumentsDirectory. For that you have to take the path of directory and append imageName like this

 NSString * documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString * documentsPathAppend = [documentsPath stringByAppendingFormat:@"/%@",[userProfileImageUrl lastPathComponent]];

And you have to write image with folowing condition

    if(![[NSFileManager defaultManager]fileExistsAtPath:documentsPathAppend])
    {
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:userProfileImageUrl]]];
   [data writeToFile:documentsPathAppend atomically:YES];
    }

After that you have to add this path into your local storage like core data. From next time you have to check whether image is there or not for particular URL in your core data.If it is there, then fetch the path from your core data and show like this

[self.profileImageView setImage:[UIImage imageWithContentsOfFile:imageEntity.imagePath]];
wesley
  • 859
  • 5
  • 15
  • thanks! and then would I set the image like this with URLWithString:documentsPathAppend inplace of the userProfileImageUrl?: UIImage *userImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:documentsPathAppend]]]; – hanumanDev Nov 11 '13 at 12:33
  • @hanumanDev, if you just wants download image and fetch from documents directory,then put else which will have [self.profileImageView setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:documentsPathAppend]]]]; No need to go with core data – wesley Nov 11 '13 at 13:29
  • If you wants to download image and store permanently,then go with my updated answer – wesley Nov 11 '13 at 13:30
0

try this method to store UIImage in Local Directory..

- (void)addImage:(UIImage *)image toCacheWithIdentifier:(NSString *)identifier {

    NSString *folderPath = @"LOCAL DIRECTORY PATH ";
    if(![[NSFileManager defaultManager] fileExistsAtPath:folderPath isDirectory:nil]) 
    {

        [[NSFileManager defaultManager] createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:nil];
    }

   NSString *fileName = [NSString stringWithFormat:@"%@.png",identifier];
   fileName = [folderPath stringByAppendingPathComponent:fileName];
   NSData *imageData = UIImagePNGRepresentation(image);
   [imageData writeToFile:fileName atomically:YES];
}

to retrieve image from Local Directory try this method...

- (UIImage *)imageFromCacheWithIdentifier:(NSString *)identifier 
{
     NSString *folderPath = @"LOCAL DIRECTORY PATH ";
     NSString *fileName = [NSString stringWithFormat:@"%@.png",identifier];
     fileName = [folderPath stringByAppendingPathComponent:fileName];

     if([UIImage imageWithContentsOfFile:fileName]) 
     {
         return [UIImage imageWithContentsOfFile:fileName];
     }
     return nil;
 }
Shaik Riyaz
  • 11,204
  • 7
  • 53
  • 70
Vaisakh
  • 2,919
  • 4
  • 26
  • 44
0

One other viable approach is to utilize NSURLCache (see also: Understanding Cache Access) in the official documentation.

The HTTP Cache was invented exactly for this requirement: Caching in HTTP in RFC 2616.

Unfortunately, HTTP Caching is an advanced topic, and the exact behavior of NSURLCache is quite obscure.

CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67