title: Swift updating UITableView with new data
body: <p>I'm trying to repopulate my <code>UITableView</code> with data from another JSON call.</p>
  
  <p>However my current setup doesn't seem to work, and while there are many identical questions on SO the answers I could find I've already tried.</p>
  
  <p>I'm saving my API data in <code>CoreData</code> entity objects. And I'm filling my UITableView with my <code>CoreData</code> entities.</p>
  
  <p>In my current setup I have 3 different API Calls that has a different amount of data, and of course different values. I need to be able to switch between these 3 datasets, and that's what I'm trying to accomplish now. (so far without progress).</p>
  
  <p>I have a function called "loadSuggestions", which is where I assume my fault lies.</p>
  
  <ul>
  <li><p>First I check for an internet connection.</p></li>
  <li><p>I set the managedObjectContext</p></li>
  <li><p>I check what API I need to call (This is determined before the function is called, and I checked that it works as intended)</p></li>
  <li><p>I delete all the current data from the entity that it's trying to call. (I also tried to delete the data from the last data the <code>UITableView</code> had loaded. That didn't change anything). I also checked that this works. After deleting the data, I checked that it prints out an empty array, I also tried logging the objects it deletes to make sure.</p></li>
  <li><p>I then fetch the new data, save it into temporary variables. Then save it to my core data.</p></li>
  <li><p>Then I make my second API call (dependant on a variable from the first one), fetch that data and save it the same way.</p></li>
  <li><p>I append the object to the array the <code>UITableView</code> fills it's cells from. (I checked that it prints out correctly as well)</p></li>
  <li><p>And lastly I reload the tableView. (doesn't change a thing)</p></li>
  </ul>
  
  <p>Here's the function:</p>
  
  <pre><code>func loadSuggestions() {
      println("----- Loading Data -----")
      // Check for an internet connection.
      if Reachability.isConnectedToNetwork() == false {
          println("ERROR: -&gt; No Internet Connection &lt;-")
      } else {
          // Set the managedContext again.
          managedContext = appDelegate.managedObjectContext!
  
          // Check what API to get the data from
          if Formula == 0 {
              formulaEntity = "TrialFormulaStock"
              println("Setting Entity: \(formulaEntity)")
              formulaAPI = NSURL(string: "http://api.com/json/entry_weekly.json")
          } else if Formula == 1 {
              formulaEntity = "ProFormulaStock"
              println("Setting Entity: \(formulaEntity)")
              formulaAPI = NSURL(string: "http://api.com/json/entry_weekly.json")
          } else if Formula == 2 {
              formulaEntity = "PremiumFormulaStock"
              formulaAPI = NSURL(string: "http://api.com/json/proff_weekly.json")
              println("Setting Entity: \(formulaEntity)")
          } else if Formula == 3 {
              formulaEntity = "PlatinumFormulaStock"
              println("Setting Entity: \(formulaEntity)")
              formulaAPI = NSURL(string: "http://api.com/json/fund_weekly.json")
          }
  
          // Delete all the current objects in the dataset
          let fetchRequest = NSFetchRequest(entityName: formulaEntity)
          let a = managedContext.executeFetchRequest(fetchRequest, error: nil) as! [NSManagedObject]
          for mo in a {
              managedContext.deleteObject(mo)
          }
  
          // Removing them from the array
          stocks.removeAll(keepCapacity: false)
          // Saving the now empty context.
          managedContext.save(nil)
  
          // Set up a fetch request for the API data
          let entity =  NSEntityDescription.entityForName(formulaEntity, inManagedObjectContext:managedContext)
          var request = NSURLRequest(URL: formulaAPI!)
          var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)
          var formula = JSON(data: data!)
  
          // Loop through the api data.
          for (index: String, actionable: JSON) in formula["actionable"] {
  
              // Save the data into temporary variables
              stockName = actionable["name"].stringValue
              ticker = actionable["ticker"].stringValue
              action = actionable["action"].stringValue
              suggestedPrice = actionable["suggested_price"].floatValue
              weight = actionable["percentage_weight"].floatValue
  
              // Set up CoreData for inserting a new object.
              let stock = NSManagedObject(entity: entity!,insertIntoManagedObjectContext:managedContext)
  
              // Save the temporary variables into coreData
              stock.setValue(stockName, forKey: "name")
              stock.setValue(ticker, forKey: "ticker")
              stock.setValue(action, forKey: "action")
              stock.setValue(suggestedPrice, forKey: "suggestedPrice")
              stock.setValue(weight, forKey: "weight")
  
              // Get ready for second API call.
              var quoteAPI = NSURL(string: "http://dev.markitondemand.com/Api/v2/Quote/json?symbol=\(ticker)")
  
              // Second API fetch.
              var quoteRequest = NSURLRequest(URL: quoteAPI!)
              var quoteData = NSURLConnection.sendSynchronousRequest(quoteRequest, returningResponse: nil, error: nil)
              if quoteData != nil {
                  // Save the data from second API call to temporary variables
                  var quote = JSON(data: quoteData!)
                  betterStockName = quote["Name"].stringValue
                  lastPrice = quote["LastPrice"].floatValue
  
                  // The second API call doesn't always find something, so checking if it exists is important.
                  if betterStockName != "" {
                      stock.setValue(betterStockName, forKey: "name")
                  }
  
                  // This can simply be set, because it will be 0 if not found.
                  stock.setValue(lastPrice, forKey: "lastPrice")
  
              } else {
                  println("ERROR ----------------- NO DATA for \(ticker) --------------")
              }
  
              // Error handling
              var error: NSError?
              if !managedContext.save(&amp;error) {
                  println("Could not save \(error), \(error?.userInfo)")
              }
              // Append the object to the array. Which fills the UITableView
              stocks.append(stock)
  
          }
  
          // Reload the tableview with the new data.
          self.tableView.reloadData()
      }
  }
  </code></pre>
  
  <p>Currently, when I push to this viewController, this function is called in <code>viewDidAppear</code> like so:</p>
  
  <pre><code>override func viewDidAppear(animated: Bool) {
      super.viewDidAppear(true)
  
      tableView.allowsSelection = true
      if isFirstTime {
          loadSuggestions()
          isFirstTime = false
      }
  }
  </code></pre>
  
  <p>It populates the tableView correctly and everything seems to work as planned.</p>
  
  <p>However if I open my slide-out menu and call a function to load different data, nothing happens, here's an example function:</p>
  
  <pre><code>func platinumFormulaTapGesture() {
      // Menu related actions
      selectView(platinumFormulaView)
      selectedMenuItem = 2
      // Setting the data to load
      Formula = 3
      // Sets the viewController. (this will mostly be the same ViewController)
      menuTabBarController.selectedIndex = 0
      // Set the new title
      navigationController?.navigationBar.topItem!.title = "PLATINUM FORMULA"
      // And here I call the loadSuggestions function again. (this does run)
      SuggestionsViewController().loadSuggestions()
  }
  </code></pre>
  
  <p>Here's the 2 relevant tableView functions:</p>
  
  <p>number of Rows:</p>
  
  <pre><code>func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
      return stocks.count
  }
  </code></pre>
  
  <p>And cellForRowAtIndexPath, (this is where I set up my cells with the CoreData)</p>
  
  <pre><code>func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -&gt; UITableViewCell {
      let cell = tableView.dequeueReusableCellWithIdentifier("com.mySuggestionsCell", forIndexPath: indexPath) as! mySuggestionsCell
  
      let formulaStock = stocks[indexPath.row]
      cell.stockNameLabel.text = formulaStock.valueForKey("name") as! String!
      cell.tickerLabel.text = formulaStock.valueForKey("ticker") as! String!
      action = formulaStock.valueForKey("action") as! String!
      suggestedPrice = formulaStock.valueForKey("suggestedPrice") as! Float
  
      let suggestedPriceString = "Suggested Price\n$\(suggestedPrice.roundTo(2))" as NSString
      var suggestedAttributedString = NSMutableAttributedString(string: suggestedPriceString as String)
  
      suggestedAttributedString.addAttributes(GrayLatoRegularAttribute, range: suggestedPriceString.rangeOfString("Suggested Price\n"))
      suggestedAttributedString.addAttributes(BlueHalisRBoldAttribute, range: suggestedPriceString.rangeOfString("$\(suggestedPrice.roundTo(2))"))
      cell.suggestedPriceLabel.attributedText = suggestedAttributedString
  
      if action == "SELL" {
          cell.suggestionContainer.backgroundColor = UIColor.formulaGreenColor()
      }
  
      if let lastPrice = formulaStock.valueForKey("lastPrice") as? Float {
          var lastPriceString = "Last Price\n$\(lastPrice.roundTo(2))" as NSString
          var lastAttributedString = NSMutableAttributedString(string: lastPriceString as String)
  
          lastAttributedString.addAttributes(GrayLatoRegularAttribute, range: lastPriceString.rangeOfString("Last Price\n"))
  
          percentDifference = ((lastPrice/suggestedPrice)*100.00)-100
  
          if percentDifference &gt; 0 &amp;&amp; action == "BUY" {
              lastAttributedString.addAttributes(RedHalisRBoldAttribute, range: lastPriceString.rangeOfString("$\(lastPrice.roundTo(2))"))
          } else if percentDifference &lt;= 0 &amp;&amp; percentDifference &gt; -100 &amp;&amp; action == "BUY" {
              lastAttributedString.addAttributes(GreenHalisRBoldAttribute, range: lastPriceString.rangeOfString("$\(lastPrice.roundTo(2))"))
          } else if percentDifference &lt;= 0 &amp;&amp; percentDifference &gt; -100 &amp;&amp; action == "SELL" {
              lastAttributedString.addAttributes(RedHalisRBoldAttribute, range: lastPriceString.rangeOfString("$\(lastPrice.roundTo(2))"))
          } else if percentDifference == -100 {
              lastPriceString = "Last Price\nN/A" as NSString
              lastAttributedString = NSMutableAttributedString(string: lastPriceString as String)
  
              lastAttributedString.addAttributes(GrayLatoRegularAttribute, range: lastPriceString.rangeOfString("Last Price\n"))
              lastAttributedString.addAttributes(BlackHalisRBoldAttribute, range: lastPriceString.rangeOfString("N/A"))
          }
  
          cell.lastPriceLabel.attributedText = lastAttributedString
      } else {
          println("lastPrice nil")
      }
  
      weight = formulaStock.valueForKey("weight") as! Float
      cell.circleChart.percentFill = weight
      let circleChartString = "\(weight.roundTo(2))%\nWEIGHT" as NSString
      var circleChartAttributedString = NSMutableAttributedString(string: circleChartString as String)
      circleChartAttributedString.addAttributes(BlueMediumHalisRBoldAttribute, range: circleChartString.rangeOfString("\(weight.roundTo(2))%\n"))
      circleChartAttributedString.addAttributes(BlackSmallHalisRBoldAttribute, range: circleChartString.rangeOfString("WEIGHT"))
      cell.circleChartLabel.attributedText = circleChartAttributedString
  
      cell.selectionStyle = UITableViewCellSelectionStyle.None
      return cell
  }
  </code></pre>
  
  <p>I define my appDelegate as the very first thing in my class:</p>
  
  <pre><code>let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
  var managedContext = NSManagedObjectContext()
  </code></pre>
  
  <p>I think that's all the code that could possibly be the cause of the bug. Again I think the most likely cause would be in the <code>loadSuggestions</code> function.</p>
  
  <p>To force update the tableView I also tried calling <code>setNeedsDisplay</code> and <code>setNeedsLayout</code> both on <code>self.view</code> and <code>tableView</code>, neither of which seemed to do anything at all.</p>
  
  <p>Any advice in figuring out why this tableView refuses to update would be an enormous help!</p>
  
  <p>And I apologize for the walls of code, but I havn't been able to find the exact origin of the issue.</p>