title: iOS 8 Swift: Trying to delete data in detail view of table view
body: <p>I used the single-view template and created a navigation controller with a ViewController that's a table view with a list of continents (read in from a plist). Clicking on a row pushes to a DetailViewController with a table view that shows some of the countries in that continent. In this DetailViewController I implemented the Edit button so a country could be deleted. Up to this point everything works great. Then when you tap the Back button to return to the continents table, when you select the same continent, the country you just deleted is listed again. I had written the same exact app in Objective-C in iOS 6 and the country that you deleted remained gone. Same problem exists when I reorder rows as well.</p>
  
  <pre><code>class ViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {
  
  var continentData = NSDictionary()
  
  override func viewDidLoad() {
      let path = NSBundle.mainBundle().pathForResource("continents", ofType: "plist")
      continentData = NSDictionary(contentsOfFile: path!)
      super.viewDidLoad()
  }
  
  override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
      return continentData.count
  }
  
  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -&gt; UITableViewCell {
      let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) as UITableViewCell
      let continents = continentData.allKeys as [String]
      cell.textLabel?.text=continents[indexPath.row]
      return cell
  }
  
  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
      if segue.identifier=="countrysegue"{
          var countryVC:DetailViewController=segue.destinationViewController as DetailViewController
          let indexPath:NSIndexPath=tableView.indexPathForSelectedRow()!
          var continents = continentData.allKeys as [String]
          countryVC.title=continents[indexPath.row]
          countryVC.countryList=continentData.objectForKey(countryVC.title!) as [String]
      }
  }
  </code></pre>
  
  <p>Then the DetailViewController:</p>
  
  <pre><code>class DetailViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate  {
  
  var countryList = [String]()
  
  override func viewWillAppear(animated: Bool) {
      //tableView.reloadData()
  }
  
  override func viewDidLoad() {
      super.viewDidLoad()
      self.navigationItem.rightBarButtonItem = self.editButtonItem()
  }
  
  override func numberOfSectionsInTableView(tableView: UITableView) -&gt; Int {
      return 1
  }
  
  override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
      return countryList.count
  }
  
  
  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -&gt; UITableViewCell {
      let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) as UITableViewCell
      cell.textLabel?.text=countryList[indexPath.row]
      return cell
  }
  
  
  override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -&gt; Bool {
      return true
  }
  
  override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
      if editingStyle == .Delete {
          countryList.removeAtIndex(indexPath.row)
          tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
      } else if editingStyle == .Insert {
  //not implemented
  }
  }
  
  override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
      let fromRow=fromIndexPath.row
      let toRow=toIndexPath.row
      let moveCountry=countryList[fromRow]
      countryList.removeAtIndex(fromRow)
      countryList.insert(moveCountry, atIndex: toRow)
  }
  
  override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -&gt; Bool {
      return true
  }
  </code></pre>
  
  <p>I haven't been able to find anything online where the delete is being done in the detail view controller. My guess is that in Objective-C NSMutableArray was passed by reference and in Swift Array is being passed by value. What's the best way to get this to work, use an unwind segue and method to pass the array back to the master view controller? Thanks in advance. - AJP</p>
  
  <p>I also thought the problem might be that the array was being passed by value and not by reference. So I created a data model class </p>
  
  <pre><code>class Continents {
      var continentData = NSMutableDictionary()
      var continents = [String]()
      var countries = [String]()
  }
  </code></pre>
  
  <p>and created an instance of it in the master view controller </p>
  
  <pre><code>var continentList=Continents()
  </code></pre>
  
  <p>and in my detail view controller</p>
  
  <pre><code>var continentCountries = Continents()
  </code></pre>
  
  <p>Then I updated prepareForSegue</p>
  
  <pre><code>override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
          if segue.identifier=="countrysegue"{
              var countryVC:DetailViewController=segue.destinationViewController as DetailViewController
              let indexPath:NSIndexPath=tableView.indexPathForSelectedRow()!
              countryVC.title=continentList.continents[indexPath.row]
              countryVC.continentCountries.countries=continentList.continentData.objectForKey(countryVC.title!) as [String]
          }
      }
  </code></pre>
  
  <p>In the detail I updated the following to handle the delete: </p>
  
  <pre><code>override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
          NSLog("\(continentCountries.countries)")
          if editingStyle == .Delete {
              continentCountries.countries.removeAtIndex(indexPath.row)
              tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
          }} 
  </code></pre>
  
  <p>Still having the same behavior, the delete works but the next time I got back in to that continent the country I deleted is still there. How can I make sure it's being passed by reference using Swift? Thanks.</p>
  
  <p>As suggested I now pass the whole object and the selected index.</p>
  
  <pre><code>    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
      if segue.identifier=="countrysegue"{
          var countryVC=segue.destinationViewController as DetailViewController
          let indexPath:NSIndexPath=tableView.indexPathForSelectedRow()!
          countryVC.title=continentList.continents[indexPath.row]
          countryVC.continentCountries=continentList
          countryVC.selectedContinent=indexPath.row
      }
  </code></pre>
  
  <p>In the detail view controller:</p>
  
  <pre><code>    override func viewWillAppear(animated: Bool) {
      continentCountries.continents = continentCountries.continentData.allKeys as [String]
      let chosenContinent = continentCountries.continents[selectedContinent]
      continentCountries.countries = continentCountries.continentData.objectForKey(chosenContinent) as [String]
      tableView.reloadData()
  }
  </code></pre>
  
  <p>But the behavior is still the same. Is it the casting to an Array? Or how I delete a row?</p>
  
  <pre><code>    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
      if editingStyle == .Delete {
          continentCountries.countries.removeAtIndex(indexPath.row)
          tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
      } 
  }
  </code></pre>
  
  <p>Thanks.</p>