1

I am trying to update a list of cells UITableView every time an element is finished being parsed in an XML file.

I attempt to do so by running the following code in my UITableViewController:

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
        if ([elementName isEqualToString:@"item"]) {
            [self.tableView reloadData];
        }
    }

    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
    {
        if (!([string isEqualToString:@"\n  "] || [string isEqualToString:@"\n"])) {
            [_idArray addObject:string];
        }
    }

Using breakpoints I can see that the line [self.tableview reloadData] is being called after every element finishes. However, the tableview does not update with the proper text.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    // Configure the cell...
    if (_idArray.count > 0) {
        [cell.detailTextLabel setText:[_idArray objectAtIndex:indexPath.row]];
    }

    return cell;
}

I am setting the numberofrowsinsection to _idArray.count and the numberofsectionsintableview to 1

The TableView is set properly to be the delegate and datasource in this file

if I add a sleep(1) after each reloadData it waits one second and NSLogs properly, but does not reload the actual table.

When the entire file is done parsing, they all suddenly appear properly.

How do I have them appear incrementally in the right way?

TestinginProd
  • 1,085
  • 1
  • 15
  • 35
  • 1
    What queue is your XML parsing running on? If it is parsing the result of a network operation, it probably isn't the main queue. UI updates need to be dispatched on the main queue. Rather than reloading the whole table it is better if you insert the newly added row too – Paulw11 May 17 '17 at 00:18
  • Agree 100% with @Paulw11. See here for placing the reload on the main (if it isn't or if you're not sure). http://stackoverflow.com/a/7905497/294949. Your numberOfRows in section ought to answer self.idArray.count, so there should never need to be a check for it's count in cellForRowAtIndexPath. – danh May 17 '17 at 00:20
  • @DCIndieDev pls check my answer – GeneCode May 17 '17 at 10:34

1 Answers1

1

Try this- wrap the reloadData in main queue GCD (Grand Central Dispatch)

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
        if ([elementName isEqualToString:@"item"]) {
           dispatch_async(dispatch_get_main_queue(), ^{
              [self.tableView reloadData];
           }
        }
}
GeneCode
  • 7,545
  • 8
  • 50
  • 85