title: iOS Refresh button in View Controller Nav: reloading all tableViewCells created from parsed JSON when clicked
body: <p>I've got a fairly important conceptual issue that many people have asked about, but there isn't a readily available clear answer to be found by searching.</p>
  
  <p>My application is simple: Several rows of TableViewCells populated with data from a parsed JSON feed. When a cell is clicked on, that cell's info is passed to a SecondViewController and displayed. The JSON feed is also stored to a .plist and in the case that the internet is not available, the TableViewCells are populated from the .plist.</p>
  
  <p>This is all working great.</p>
  
  <p>However, the last thing I need is a refresh button at the top of my FirstViewController to refresh the JSON feed, and all of the cells in the table with the new data from the new variables. However, I've encountered an issue with implementing this:</p>
  
  <p>My original JSON call, and variables to populate the cells are located in the ViewDidLoad method. When the view loads, these variables are "set" and don't refresh. Further, I can move the JSON call and variables into viewWillLoad - which will refresh the table each time after clicking on a cell, and then clicking "back" to the firstViewController -- this will update the JSON and cells successfully, however it does impact the speed and makes the view controller "pause" when going back to the MainViewController, which makes calling my original JSON and setting my variables in viewWillLoad an unviable option.</p>
  
  <p>I have created a reload button in ViewDidLoad, which is linked to an IBAction method "refresh":</p>
  
  <p><strong>Create Button Programitically in ViewDidLoad:</strong></p>
  
  <pre><code>// Reload issues button
  UIBarButtonItem *button = [[UIBarButtonItem alloc]
                             initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
                             target:self
                             action:@selector(refresh:)];
  self.navigationItem.rightBarButtonItem = button;
  [button release];
  </code></pre>
  
  <p><strong>Action Method it's linked to:</strong></p>
  
  <pre><code>- (IBAction)refresh:(id)sender {
  
      myRawJson = [[NSString alloc] initWithContentsOfURL:[NSURL  
                                    URLWithString:@"http://www.yoursite.com/json.JSON"]  
                                    encoding:NSUTF8StringEncoding 
                                    error:nil];
  
      SBJsonParser *parser = [[SBJsonParser alloc] init];
      NSDictionary * myParsedJson = [parser objectWithString:myRawJson error:NULL];
  
  // New updated dictionary built from refreshed JSON
      allLetterContents = [myParsedJson objectForKey:@"nodes"];
  
  // Log the new refreshed JSON
      NSLog(@"You clicked refresh. Your new JSON is %@", myRawJson);
  
      //Maybe use the notification center?? But don't know how to implement.
      //[[NSNotificationCenter defaultCenter] addObserver:self 
                                              selector:@selector(refreshView:) 
                                              name:@"refreshView" object:nil];
      //[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshView" 
                                              object:nil];
  
      }
  
      [self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows] 
                       withRowAnimation:UITableViewRowAnimationNone];
  
      [myRawJson release];
  }
  </code></pre>
  
  <p>In the code above you can see that I'm re-calling the JSON each time the button is clicked and logging a message to console with the new JSON. This is working. I've even re-built a dictionary which is successfully adding the new content.</p>
  
  <p>My question is: How can I make the tableViewCells "refresh" with this new data as well? Can I just make the button re-load the entire view controller - so it would call ViewDidLoad again? Do I need to re-think my apps structure, or move my original variables out of viewDidLoad?</p>
  
  <p>I've been reading some posts on the NSNotificationCenter, but the implementation of this still baffles me, as I'm fairly new to iOS development.</p>
  
  <p>Thanks~</p>
  
  <hr>
  
  <p><strong>Update:</strong></p>
  
  <hr>
  
  <p>It's still not updating. Here is my full refresh button code with [self.tableView reloadData]; called at the end of my IBAction. </p>
  
  <pre><code>    - (IBAction)refresh:(id)sender {
          [DSBezelActivityView newActivityViewForView:        
                           self.navigationController.navigationBar.superview     
                           withLabel:@"Loading Feed..." width:160];
  
          myRawJson = [[NSString alloc] initWithContentsOfURL:[NSURL 
                       URLWithString:@"http://site.com/mobile.JSON"] 
                       encoding:NSUTF8StringEncoding 
                       error:nil];
  
          SBJsonParser *parser = [[SBJsonParser alloc] init];
          NSDictionary * myParsedJson = [parser objectWithString:myRawJson error:NULL];
          allLetterContents = [myParsedJson objectForKey:@"nodes"];
  
          BOOL isEmpty = ([myParsedJson count] == 0);
  
          if (isEmpty) {
              NSString *refreshErrorMessage = [NSString 
  stringWithFormat:@"An internet or network connection is required."];
              UIAlertView *alert = [[UIAlertView alloc] 
                                   initWithTitle:@"Alert" 
                                   message: refreshErrorMessage 
                                   delegate:self 
                                   cancelButtonTitle:@"Close" 
                                   otherButtonTitles:nil];
              [alert show];
              [alert release];
  
              allLetterContents = [NSMutableDictionary 
                                  dictionaryWithContentsOfFile:[self saveFilePath]];
              //NSLog(@"allLetterContents from file: %@", allLetterContents);
  
          } else {
  
          NSLog(@"Your new allLetterContents is %@",  allLetterContents);
  
            // Fast enumeration through the allLetterContents NSMutableDictionary
            for (NSMutableDictionary * key in allLetterContents) {
              NSDictionary *node = [key objectForKey:@"node"];
              NSMutableString *contentTitle = [node objectForKey:@"title"];        
              NSMutableString *contentNid = [node objectForKey:@"nid"];
              NSMutableString *contentBody = [node objectForKey:@"body"];
              // Add each Title and Nid to specific arrays
              //[self.contentTitleArray addObject:contentTitle];
              [self.contentTitleArray addObject:[[contentTitle 
                                       stringByReplacingOccurrencesOfString:@"&amp;amp;" 
                                       withString:@"&amp;"] mutableCopy]];
              [self.contentNidArray addObject:contentNid];
              [self.contentBodyArray addObject:contentBody];
            }
  
          }
  
          [self.tableView reloadData];
  
          [DSBezelActivityView removeViewAnimated:YES];
          [myRawJson release];
      }
  </code></pre>
  
  <p>I'm configuring the cell at cellForRowAtIndexPath (<strong>Updated: Posted entire method</strong>):</p>
  
  <pre><code>- (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] autorelease];
          if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
              cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
          }
      }
  
      // Configure the cell.
      cell.textLabel.text = [self.contentTitleArray objectAtIndex: [indexPath row]];
      cell.detailTextLabel.text = [self.contentNidArray objectAtIndex: [indexPath row]];
      return cell;
  }
  </code></pre>
  
  <p>Setting it on didSelectRowAtIndexPath:</p>
  
  <pre><code>self.detailViewController.currentNodeTitle = [contentTitleArray 
                                               objectAtIndex:indexPath.row];
  self.detailViewController.currentNodeNid= [contentNidArray 
                                            objectAtIndex:indexPath.row];
  self.detailViewController.currentNodeBody = [contentBodyArray 
                                              objectAtIndex:indexPath.row];
  </code></pre>
  
  <p>So when clicking my refresh button the table should* refresh with the new json, but does not.. Am I missing a step?</p>
  
  <p><img src="https://i.stack.imgur.com/xpyrm.png" alt="enter image description here"></p>
  
  <p>Additionally this may not be important, but I'm changing the colors for every other row with:</p>
  
  <pre><code>// Customize the appearance of table view cells.
  -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
      if (indexPath.row % 2)
      {
          [cell setBackgroundColor:[UIColor colorWithRed:221.0/255.0 green:238.0/255.0 blue:255.0/255.0 alpha:1]];
          cell.textLabel.textColor = [UIColor colorWithRed:2.0/255.0 green:41.0/255.0 blue:117.0/255.0 alpha:1];
          cell.detailTextLabel.textColor = [UIColor colorWithRed:2.0/255.0 green:41.0/255.0 blue:117.0/255.0 alpha:1];
  
      }    else [cell setBackgroundColor:[UIColor clearColor]];
  }
  </code></pre>
  
  <p><strong>Update</strong></p>
  
  <p><img src="https://i.stack.imgur.com/OoO6q.png" alt="enter image description here"></p>