Storing and retrieving images from documents directory in tableView?

强颜欢笑 提交于 2019-12-12 00:43:38

问题


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

回答1:


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



回答2:


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.




回答3:


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)



来源:https://stackoverflow.com/questions/37970124/storing-and-retrieving-images-from-documents-directory-in-tableview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!