Search code examples
iosparsinguiviewcontrolleruitableviewpushviewcontroller

Is there any way to pass a PFFile (image) to another controller and display it without querying the database in the new controller?


This is a question I have asked over at Parse forums and I have not had any reply from them for the past 3 days. Hence I am posting here.

Hi,

I have a PFQueryTableViewController and the table has custom cells with images and different labels. This Table navigates to another DetailViewController on the selection of a row. The DetailViewController need to display an image in its view, which we acquire from our query to the Parse database in the PFQueryTableViewController. How do I achieve that ?

TABLEVIEWCONTROLLER.M

@interface TableViewController ()

@end

NSMutableArray* detailObjects;
DetObj* clickedObj;

@implementation TableViewController

- (void)objectsDidLoad:(NSError *)error {
    [super objectsDidLoad:error];

    // This method is called every time objects are loaded from Parse via the PFQuery

    for (PFObject* object in self.objects)
    {
        DetailObj* obj = [[DetailObj alloc ] init ];
        [obj setDetName:[object objectForKey:@"detName"]];
        [mov setDetImage:[object objectForKey:@"detImage"]];
        [detailObjects addObject:obj];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
    static NSString *CellIdentifier = @"upCell";

    customBigTableCell *cell = (customBigTableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[customBigTableCell alloc] init];
    }

    cell.name.text = [object objectForKey:@"detName"];
    cell.image.file = [object objectForKey:@"detImage"];

    //this is essential for loading the image from the database
    [cell.image loadInBackground];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [super tableView:tableView didSelectRowAtIndexPath:indexPath];

    UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:[NSBundle mainBundle]];

    newDetailController* newController = [storyboard instantiateViewControllerWithIdentifier:@"Detail"];

    clickedObj = [[DetObj alloc] init];

    NSIndexPath* path = [self.tableView indexPathForSelectedRow];

    clickedObj = [detailObjects objectAtIndex:path.row];

    [newController setDetInfo:clickedObj];

    [[self navigationController] pushViewController:newController animated:YES];
}

I have tried using a PFImageView as stated below in the DetailViewController. detailInfo is the object passed from the previous PFQueryTableViewController.

newDetailController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    PFImageView* detImage = [[PFImageView alloc] initWithFrame:CGRectMake(300,0,320,150)];

    PFFile* file = detailInfo.fullImage.file;

    detImage.file = file;

    [detImage loadInBackground];

    [self.view addSubview:detImage];

}

But I have this error.

reason: '-[PFFile file]: unrecognized selector sent to instance

I dont want to query the database again to get the info I have already obtained in the previous controller.

Thanks Andrew


Solution

  • I resorted to a different approach and it works well for me. But Thanks Eddie for telling me about NSCache and its usage.

    I store the URL of the PFFile associated with the object, and then pass the URL to the next controller. Then I display the image using the following code in -(void)viewDidLoad()

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        NSData *imageData = [NSData dataWithContentsOfURL: imgURL];
    
        dispatch_async(dispatch_get_main_queue(), ^{
            // Update the UI
            self.upImage.image = [UIImage imageWithData:imageData];
        });
    });
    

    Thanks to this thread Create UIIMAGE with URL in iOS

    Thanks again. Andrew