简体   繁体   中英

UITableView With Parse Query Not Loading

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;

在此处输入图片说明

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM