icodes icodes - 5 months ago 35
iOS Question

Storing and retrieving images from documents directory in tableView?

I am trying to store images from webservice in documents directory.For a stored image I want to load it from documents directory in table view.
The images are accessible from a url such as :-

http://Address/App/User/Image/Puegeot_E7


Fetching from webservice is successful however from the documents directory I keep getting null image.Can't seem to find what's wrong here.

- (void)saveImage:(UIImage*)image withName:(NSString *)imageName
{
if (image != nil)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:imageName];

NSLog(@"Saving path %@",path); // Saving path /Users/computername/Library/Developer/CoreSimulator/Devices/7277F3D3-298C-451A-8607-8070A08650C7/data/Containers/Data/Application/D3AF4DD9-A4CD-42C8-A8EB-0F15C271EE61/Documents/CabImage/Puegeot_E7

NSData* data = UIImagePNGRepresentation(image);
[data writeToFile:path atomically:YES];
}
}

- (UIImage *)getImageFromURL:(NSString *)fileURL
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:fileURL];
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:path]];
NSLog(@"data %@",data); //This returns (null)
UIImage *result = [UIImage imageWithData:data];
return result;
}


In tableView this is how I am trying to load from documents directory.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//default initialisation stuff
NSDictionary *obj = [responseArray objectAtIndex:indexPath.row];
cell.imgVW.image = [UIImage imageNamed:@"default-car.png"];
NSString *imgPath = obj[@"cabimage"];
NSLog(@"imgPath : %@",imgPath); // imgPath : Image/Puegeot_E7
UIImage *imgFromDisk = [self getImageFromURL:imgPath];
NSLog(@"imgFromDisk - %@",imgFromDisk); -> (null)
if (imgFromDisk) {
cell.imgVW.image = imgFromDisk;
}else{
//download
NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@User/%@",BASE_URL,imgPath]];

self.task = [self.session downloadTaskWithURL:imageURL completionHandler:^(NSURL *location,NSURLResponse *response,NSError *error){
NSData *img_data = [NSData dataWithContentsOfURL:imageURL];
if (img_data) {
UIImage *img = [UIImage imageWithData:img_data];
dispatch_async(dispatch_get_main_queue(), ^{
ListCell *cell = (id)[tableView cellForRowAtIndexPath:indexPath];
cell.imgVW.image = img;
[self saveImage:img withName:imgPath];

});

}

}];
[self.task resume];

}
}

Answer

To start with, I recommend you use SDWebImage library - an asynchronous image downloader with cache support. Usage is easy enough:

[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
                      placeholderImage:[UIImage imageNamed:@"placeholder.png"]
                             completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                                ... completion code here ...
                             }];

However, if you wish to do it your own way. You should change thess 2 line of code:

UIImage *imgFromDisk = [self getImageFromURL:imgPath];

into this:

UIImage *imgFromDisk = [self getImageFromURL:[imgPath lastPathComponent]];

and

[self saveImage:img withName:imgPath];

into this:

[self saveImage:img withName:[imgPath lastPathComponent]];
Comments