Question

I'm trying to get an image from a pointer using parse. I'm trying to pull an image from a class without making a second request.

Here is the code:

PFFile * connectImageFile = [object objectForKey:@"prayerImage"];
connection.connectImage.file = connectImageFile;
[connection.connectImage loadInBackground];

The second line is what throws the following exception:

-[PFObject url]: unrecognized selector sent to instance 0x16d4f480

I am sure that I am using a PFTableViewCell (it is in a PFTableViewController) and I connectImage is a PFImageViewer in the code and the Interface Builder and it is linked. I omitted the last two lines and added: NSLog(@"%@", connectImageFile.url); for debugging purposes and still got an error:

-[PFObject url]: unrecognized selector sent to instance 0x14557680

Obviously it is a different instance but seemingly same issue... When I NSLog just connectImageFile then I just get: <prayers:W9SUTK3uL3:(null)> which is the correct objectID... so I have absolutely no idea.

EDIT: To be safe, I made a separate query for the image and still had an issue. It didn't crash when I tried to populate the PFImageView but did crash when I tried to get the url from the PFObject. Here is my code:

PFObject * prayerImageObject = [object objectForKey:@"prayerImage"];
NSLog(@"%@", prayerImageObject.objectId);

PFQuery * query = [PFQuery queryWithClassName:@"prayers"];

[query whereKey:@"ObjectId" equalTo:prayerImageObject.objectId];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    PFFile * connectImageFile = [object objectForKey:@"prayerImage"];
    connection.imageView.file = connectImageFile;

    NSLog(@"%@", connectImageFile.url);

    [connection.imageView loadInBackground];

}];

My first NSLog is giving me a good objectId and does correspond with the correct image I want to receive. My second NSLog is where the exception is thrown (very similar to the whole PFObject deal except with a different hex value).

Edit By request here is my implementation file:

    //
//  connectTableViewController.m
//  Prayer
//
//  Created by Evan Is Stupid on 12/29/13.
//  Copyright (c) 2013 Evan Stoddard. All rights reserved.
//

#import "connectTableViewController.h"
#import "connectTableViewCell.h"
#import <Parse/Parse.h>

@interface connectTableViewController ()

    @property (nonatomic, retain) connectTableViewCell * connection;

@end

@implementation connectTableViewController
@synthesize connection;

- (id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if (self) {

        // Custom the table
        // The className to query on
        self.parseClassName = @"connections";

        // Whether the built-in pull-to-refresh is enabled
        self.pullToRefreshEnabled = YES;

        // Whether the built-in pagination is enabled
        self.paginationEnabled = YES;

        // The number of objects to show per page
        self.objectsPerPage = 5;

    }
    return self;
}


- (void)viewDidLoad
{
    [super viewDidLoad];
    self.connection = [[connectTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"connectionCell"];
}

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

}

- (void)objectsWillLoad {
    [super objectsWillLoad];

}

- (PFQuery *)queryForTable {

    PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
    [query whereKey:@"username" equalTo:[PFUser currentUser]];

    // If no objects are loaded in memory, we look to the cache first to fill the table
    // and then subsequently do a query against the network.
    if ([self.objects count] == 0) {
        query.cachePolicy = kPFCachePolicyCacheThenNetwork;
    }

    return query;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {

    return [self loadTableViewObjects:object withTableView:tableView];

}

- (connectTableViewCell *)loadTableViewObjects:(PFObject *)object withTableView:(UITableView *)tableView{

    connection = [tableView dequeueReusableCellWithIdentifier:@"connectionCell"];

    PFObject * prayerImageObject = [object objectForKey:@"prayerImage"];
    NSLog(@"%@", prayerImageObject.objectId);

    PFQuery * query = [PFQuery queryWithClassName:@"prayers"];

    [query whereKey:@"ObjectId" equalTo:prayerImageObject.objectId];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        PFFile * connectImageFile = [object objectForKey:@"prayerImage"];
        connection.imageView.file = connectImageFile;

        NSLog(@"%@", connectImageFile.url);

        [connection.imageView loadInBackground];

    }];

    connection.connectTitle.text = @"Someone has prayed for you!";
    return connection;

}

@end
Was it helpful?

Solution

If you're trying to get the image that is inside an object through it's pointer, you need to call fetchfirst.

So, if I understand you question correctly, you should try:

PFObject *object... 
[object fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
    if (!error) {
        // Now get the file
        PFFile * connectImageFile = [object objectForKey:@"prayerImage"];
        // continue your code
    }
}];

UPDATE:

This is the code that works for me. Unfortunately, I couldn't do it with only one request, as you wanted. In order to do that, you must already have fetched for the object before.

    // This is the PFObject
    PFObject *object = [PFObject objectWithoutDataWithClassName:@"SomeClass" objectId:@"id"];
    // I needed to fetch the first object
    [object fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
        // Here, I get the second object, inside pointer column
        PFObject *object2 = object[@"pointer"];
        // Fetch again to get data
        [object2 fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
            // get PFFile in image column
            PFFile * file = [object2 objectForKey:@"image"];
            NSLog(@"url %@", file.url);
            // Now continue code to assign image.
        }];
    }];

If you query for the object in question, you could include key that has the pointer, that way you would use only one request.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top