0

So I have a UITableView and a Parse query, and the query is able to retrieve the objects from parse. But the TableView is no showing them.

Here is my code I'll explain more below:

- (PFQuery *)query {
    NSLog(@"hello");
    PFQuery *query = [PFQuery queryWithClassName:@"Posts"];

    // 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.


    // Query for posts near our current location.

    // Get our current location:
    //CLLocation *currentLocation = [self.dataSource currentLocationForWallPostsTableViewController:self];
    CLLocationAccuracy filterDistance = [[NSUserDefaults standardUserDefaults] doubleForKey:PAWUserDefaultsFilterDistanceKey];

    // And set the query to look by location
    PFGeoPoint *point = [PFGeoPoint geoPointWithLatitude:40.941984
                                               longitude:-72.88712399999997];
    [query whereKey:PAWParsePostLocationKey nearGeoPoint:point withinKilometers:PAWMetersToKilometers(filterDistance)];
    [query includeKey:PAWParsePostUserKey];

    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            // The find succeeded.
            NSLog(@"Successfully retrieved %lu users.", (unsigned long)objects.count);
            self.myArray = objects;
        } else {
            // Log details of the failure
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }
    }];


    NSLog(@"work");

    return query;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}



- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    return self.myArray.count;
}


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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    NSLog(@"yy");
    NSString *kk= [object objectForKey:@"text"];
    NSLog(@"%@",kk);
    // Configure the cell
    cell.textLabel.text = [object objectForKey:@"text"];

    return cell;
}

Two things that I have found out that may be causing the issue is:

  1. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section is being called before the query, which doesn't make sense to me.

  2. And because that is being called before the query the array.count is 0;

So I don't understand why that line would be called before the the query. If you have any suggestions please let me know!

Update This is being called three times, and the second nslog is not being called.

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        NSLog(@"Fsa");
        return self.myArray.count;
        NSLog(@"Successfully retrieved %lu .", (unsigned long)self.myArray.count);

    }

In my .h

UIViewController <UITableViewDataSource, UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;

enter image description here

8
  • What do you have against ParseQueryTableViewController? Commented Jan 14, 2015 at 2:47
  • @soulshined Nothing haha. I was using it but stopped because it didn't allow the customization I wanted. Commented Jan 14, 2015 at 2:48
  • And your calling this query in viewDidLoad? Commented Jan 14, 2015 at 2:51
  • @soulshined No it's in it's own separate method. Commented Jan 14, 2015 at 2:52
  • I'm feeling a bit too sick right now to write out a full comment but you're getting some poor answers... The problem lies in the fact that you're both using the - (PFQuery *)query method to populate your table and doing and asynchronous query within it to get the number of object self.myArray to populate the number of rows. That's the issue. That's why you have 0 rows. If no one's able to help you I'll help once I feel a bit better. Commented Jan 14, 2015 at 3:24

3 Answers 3

3

This method:

- (PFQuery *)queryForTable

returns a query which automatically populates the PFObject in cellForRowAtIndexPath:object: in

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

What you've done, however, is perform the query within your queryForTable method. (1) You don't need to perform the query, you simply need to return it, but (2) it seems as if you're strictly performing that query in order to populate self.myArray which you then which to use as a return value in numberOfRowsInSection:. The problem with #2 is that the query you're performing in queryForTable is performed asynchronously, so self.myArray may still be empty by the time numberOfRowsInSection: is called. So that's what's happening -- self.myArray.count = 0 and therefore cellForRowAtIndexPath: wouldn't be called being called.

But the biggest problem of all, #3, is that - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object can only be used in a PFQueryTableViewController so you'll have to use a query and the standard UITableView delegate methods instead.

Try this instead:

- (void)viewDidLoad {

    NSLog(@"hello");
    PFQuery *query = [PFQuery queryWithClassName:@"Posts"];

    // Query for posts near our current location.

    // Get our current location:
    //CLLocation *currentLocation = [self.dataSource currentLocationForWallPostsTableViewController:self];
    CLLocationAccuracy filterDistance = [[NSUserDefaults standardUserDefaults] doubleForKey:PAWUserDefaultsFilterDistanceKey];

    // And set the query to look by location
    PFGeoPoint *point = [PFGeoPoint geoPointWithLatitude:40.941984
                                               longitude:-72.88712399999997];
    [query whereKey:PAWParsePostLocationKey nearGeoPoint:point withinKilometers:PAWMetersToKilometers(filterDistance)];
    [query includeKey:PAWParsePostUserKey];

    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            // The find succeeded.
            NSLog(@"Successfully retrieved %lu users.", (unsigned long)objects.count);
            self.myArray = objects;

            dispatch_async(dispatch_get_main_queue(), ^{
                [self.tableView reloadData];
            });

        } else {
            // Log details of the failure
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }
    }];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.myArray.count;
}

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    NSLog(@"yy");
    NSString *kk= [[self.myArray objectAtIndex:indexPath.row] objectForKey:@"text"];
    NSLog(@"%@",kk);
    // Configure the cell
    cell.textLabel.text = [[self.myArray objectAtIndex:indexPath.row] objectForKey:@"text"];

    return cell;
}
Sign up to request clarification or add additional context in comments.

14 Comments

Do I still need tableView:numberOfRowsInSection? I'm using a tableView in a regular viewcontroller.
@Jack In using the - (PFQuery *)query method, did you actually mean to use a - (PFQuery *)queryForTable method instead?
@Jack Cool... That makes more sense. I don't think tableView:numberOfRowsInSection is required (I don't think number of sections is required either but I left that in there), but you can try my update and see what happens. If you really wanted to use tableView:numberOfRowsInSection though you can get wait for a response from objectsDidLoad: and set self.array in that method.
Okay I added all that but now it crashes and I'm getting this: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Feed tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7fe832d46e10'
@Jack OK, we'll delete numberOfRowsInSection: then... How about now?
|
1

Try this:

[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if (!error) {
        // The find succeeded.
        NSLog(@"Successfully retrieved %lu users.", (unsigned long)objects.count);
        self.myArray = objects;
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.tableView reloadData];
        });

    } else {
        // Log details of the failure
        NSLog(@"Error: %@ %@", error, [error userInfo]);
    }
}];

6 Comments

I just tried this and I it crashed saying:'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:' But I have the dataSource and delegates linked.
I'm pretty sure this is the correct solution for the problem in your question: the UITableView is now trying to display the data. You need to make sure -tableView:cellForRowAtIndexPath: returns a valid cell, but this is a different problem. I doubt your -tableView:cellForRowAtIndexPath:object: method is called.
@ThomasMüller This isn't the correct answer unfortunately and tableView:cellForRowAtIndexPath: isn't being called because numberOfRowsInSection is returning 0... I'll try to write up an answer because I think this question's quickly going down a rabbit hole...
@LyndseyScott With this answer the tableView is told to reload its data on the main thread. To me it looks like numberOfRowsInSection is returning something greater than 0, then tableView:cellForRowAtIndexPath: is being called and results in an error because (I guess) it's not properly implemented and doesn't return a cell.
@ThomasMüller The OP is using this method though: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object which expects to be populated by the results of a query, but that method will only work in a PFQueryTableViewController, which the OP is NOT using. There are many issues with the code and this answer doesn't really cover them.
|
0

Try explicitly calling it in viewDidLoad. Provided self.myArray = objects doesn't return nil this should suffice. It will force it to load circumventing other methods loading first:

-(void)viewDidLoad {
    ...
    [self locationQuery];
}

-(PFQuery *)locationQuery {

    CLLocationAccuracy filterDistance = [[NSUserDefaults standardUserDefaults] doubleForKey:PAWUserDefaultsFilterDistanceKey];
    PFGeoPoint *point = [PFGeoPoint geoPointWithLatitude:40.941984
                                           longitude:-72.88712399999997];

    PFQuery *query = [PFQuery queryWithClassName:@"Posts"];
    [query whereKey:PAWParsePostLocationKey nearGeoPoint:point withinKilometers:PAWMetersToKilometers(filterDistance)];
    [query includeKey:PAWParsePostUserKey];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
            if (!error) {
                // The find succeeded.
                NSLog(@"Successfully retrieved %lu users.", (unsigned long)objects.count); 
                self.myArray = objects;
                //OR : 
                self.myArray = [objects valueForKey:@"NameOfParse.comClassColumnHere"];
                [self.tableView reloadData];
            } else {
                // Log details of the failure
                NSLog(@"Error: %@ %@", error, [error userInfo]);
            }
     }];
        return query;
}

Additionally, your cell.textLabel.text is referencing something that doesn't exist..

NSString *kk= [object objectForKey:@"text"]; NSLog(@"%@",kk); // Configure the cell cell.textLabel.text = [object objectForKey:@"text"];

what is this? if you want it to be the array you queried you have to do :

cell.textLabel.text = [NSString stringWithFormat:@"%@", [self.myArray objectAtIndex:indexPath.row]];

16 Comments

@Jack I asked that. If you mean you have different query just name the method something else, it doesn't matter.
yes the names are different, but I already had something in my viewDidLoad calling the query.
that code is relevant, show it @Jack or simply delete it, and do the void method I explained.
I added the code you provide but I'm still getting the same issue. Look at the update on the question.
@Jack is self.myArray = objects; returning values? NSLog self.myArray in stead of the number
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.