Reputation: 1457
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];
}
}
Upvotes: 0
Views: 888
Reputation: 6963
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]];
Upvotes: 0
Reputation: 144
You're getting nil
because you're not providing the correct path where to retrieve the image.
You just use the name of the image but you should use the same path as where you saved it.
So put:
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:imageName];
In your getImageFromURL
method.
Do not just use the image name to retrieve your image. Hope this helps!
(Sorry for the bad layout of my text, I'm typing on my phone)
Upvotes: 1
Reputation: 62676
The problem seems apparent from what you're seeing in the logs:
NSLog(@"imgPath : %@",imgPath); // imgPath : Image/Puegeot_E7
That path isn't in the documents directory.
To get firmer control of this, have the save method return the path to where the image was saved:
- (NSString *)saveImage:(UIImage*)image withName:(NSString *)imageName{
// op code, then:
return path;
}
Test that you can read back an image. (This code is for test, not for the app).
UIImage *testImage = [UIImage imageNamed:@"some_test_image"];
NSString *path = [self saveImage:testImage withName:@"test_name"];
UIImage *didItWork = [self getImageFromURL:path];
NSLog(@"did it work? %@", didItWork);
Back to the real app... After the path returned from writing the image in your model:
UIImage *downloadedImage = // however you get this
NSString * downloadedImageName = // however you get this
NSDictionary *obj = [responseArray objectAtIndex:indexPath.row];
obj[@"cabbage"] = [self saveImage: downloadedImage withName:downloadedImageName];
Now we know that your cellForRowAtIndexPath
method will see the saved path, and we know from the test that image creation from that path will work.
Upvotes: 2