title: Tableview SearchBar For Json Data
body: <p>I'm making an app that parses JSON data &amp; populates a tableview. In this app i want to make a SearchBar to search the id's. Everything is fine with parsing and populating the tableview but I am having problem with the searching. When I run the app I am gettin the following error: <strong><em>terminating with uncaught exception of type NSException</em></strong></p>
  
  <p>I have two arrays, first one is the main one and the other one is filtered one. </p>
  
  <p><strong>Requirement:</strong> I want to search array by "DesenNo" which i declared in my model.</p>
  
  <p>Here are my codes:</p>
  
  <p>ViewController:</p>
  
  <p>import UIKit
  import Foundation
  import os.log</p>
  
  <p>class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchResultsUpdating, HomeModelProtocol  {</p>
  
  <pre><code>//Properties
  var feedItems: NSArray = NSArray()
  var detailViewController: detailsVC? = nil
  var searchActive : Bool = false
  var filteredData:[String] = []
      var resultSearchController:UISearchController!
  @IBOutlet weak var listTableView: UITableView!
  
  @IBOutlet weak var searchBar: UISearchBar!
  override func viewDidLoad() {
      super.viewDidLoad()
  
      resultSearchController = UISearchController(searchResultsController: nil)
  
      resultSearchController.searchResultsUpdater = self
  
      resultSearchController.hidesNavigationBarDuringPresentation = false
  
      resultSearchController.dimsBackgroundDuringPresentation = false
  
      resultSearchController.searchBar.searchBarStyle = UISearchBarStyle.prominent
  
      resultSearchController.searchBar.sizeToFit()
  
      self.listTableView.tableHeaderView = resultSearchController.searchBar
  
      self.listTableView.dataSource = self
  
      let homeModel = HomeModel()
      homeModel.delegate = self
      homeModel.downloadItems()
  
  }
  
  
  func itemsDownloaded(items: NSArray) {
  
      feedItems = items
      self.listTableView.reloadData()
  }
  
  
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
  
      if resultSearchController.isActive {
          return filteredData.count
      }
      else {
          return feedItems.count
      }
  
  }
  
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
      // Retrieve cell
  
      let cellIdentifier: String = "BasicCell"
      let myCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! MyTableCell
      // Get the location to be shown
      // Get references to labels of cell
       //Label1
      if resultSearchController.isActive {
          let item: LocationModel = feedItems[indexPath.row] as! LocationModel
          let desenNoToString = item.DesenNo
  
          let desenString = "\(desenNoToString)"
          let regex = try! NSRegularExpression(pattern:"\"(.*)\"")
          if let match = regex.firstMatch(
              in: desenString, range:NSMakeRange(0,desenString.utf16.count)) {
              let result = (desenString as NSString).substring(with: match.range(at:1))
              myCell.label1!.text = result
          }
  
  
          //Label2
          let dolarToString = item.Dolar
          let dolarString = "\(dolarToString)"
          if let match = regex.firstMatch(
              in: dolarString, range:NSMakeRange(0,dolarString.utf16.count)) {
              let result = (dolarString as NSString).substring(with: match.range(at:1))
              myCell.label2!.text = result
          }
  
          //Label3
          let zeminToString = item.Zemin
          let zeminString = "\(zeminToString)"
          if let match = regex.firstMatch(
              in: zeminString, range:NSMakeRange(0,zeminString.utf16.count)) {
              let result = (zeminString as NSString).substring(with: match.range(at:1))
              myCell.label3!.text = result
          }
  
          //Label4
          let renkToString = item.Renk
          let renkString = "\(renkToString)"
          if let match = regex.firstMatch(
              in: renkString, range:NSMakeRange(0,renkString.utf16.count)) {
              let result = (renkString as NSString).substring(with: match.range(at:1))
              myCell.label4!.text = result
          }
  
          //Label5
          let enToString = item.En
          let enString = "\(enToString)"
          if let match = regex.firstMatch(
              in: enString, range:NSMakeRange(0,enString.utf16.count)) {
              let result = (enString as NSString).substring(with: match.range(at:1))
              myCell.label5!.text = result
          }
  
          //Label6
          let euroToString = item.Euro
          let euroString = "\(euroToString)"
          if let match = regex.firstMatch(
              in: euroString, range:NSMakeRange(0,euroString.utf16.count)) {
              let result = (euroString as NSString).substring(with: match.range(at:1))
              myCell.label6!.text = result
          }
      }else {
          let item: LocationModel = feedItems[indexPath.row] as! LocationModel
          let desenNoToString = item.DesenNo
  
          let desenString = "\(desenNoToString)"
          let regex = try! NSRegularExpression(pattern:"\"(.*)\"")
          if let match = regex.firstMatch(
              in: desenString, range:NSMakeRange(0,desenString.utf16.count)) {
              let result = (desenString as NSString).substring(with: match.range(at:1))
              myCell.label1!.text = result
          }
  
  
          //Label2
          let dolarToString = item.Dolar
          let dolarString = "\(dolarToString)"
          if let match = regex.firstMatch(
              in: dolarString, range:NSMakeRange(0,dolarString.utf16.count)) {
              let result = (dolarString as NSString).substring(with: match.range(at:1))
              myCell.label2!.text = result
          }
  
          //Label3
          let zeminToString = item.Zemin
          let zeminString = "\(zeminToString)"
          if let match = regex.firstMatch(
              in: zeminString, range:NSMakeRange(0,zeminString.utf16.count)) {
              let result = (zeminString as NSString).substring(with: match.range(at:1))
              myCell.label3!.text = result
          }
  
          //Label4
          let renkToString = item.Renk
          let renkString = "\(renkToString)"
          if let match = regex.firstMatch(
              in: renkString, range:NSMakeRange(0,renkString.utf16.count)) {
              let result = (renkString as NSString).substring(with: match.range(at:1))
              myCell.label4!.text = result
          }
  
          //Label5
          let enToString = item.En
          let enString = "\(enToString)"
          if let match = regex.firstMatch(
              in: enString, range:NSMakeRange(0,enString.utf16.count)) {
              let result = (enString as NSString).substring(with: match.range(at:1))
              myCell.label5!.text = result
          }
  
          //Label6
          let euroToString = item.Euro
          let euroString = "\(euroToString)"
          if let match = regex.firstMatch(
              in: euroString, range:NSMakeRange(0,euroString.utf16.count)) {
              let result = (euroString as NSString).substring(with: match.range(at:1))
              myCell.label6!.text = result
          }
      }
  
  
      return myCell
  }
  func updateSearchResults(for searchController: UISearchController) {
  
      if searchController.isActive {
  
          filteredData.removeAll(keepingCapacity: false)
          let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
          let array = (feedItems as NSArray).filtered(using: searchPredicate)
          filteredData = array as! [String]
          listTableView.reloadData()
  
      }
      else {
  
          filteredData.removeAll(keepingCapacity: false)
  
          filteredData = feedItems as! [String]
  
          listTableView.reloadData()
  
      }
  
  
  }
  </code></pre>
  
  <p>}</p>
  
  <p>LocationModel.Swift</p>
  
  <p>import UIKit</p>
  
  <p>class LocationModel: NSObject {</p>
  
  <pre><code>//properties
  
  var DesenNo: String?
  var Dolar: String?
  var Zemin: String?
  var En: String?
  var Euro: String?
  var Renk: String?
  
  
  
  
  //empty constructor
  
  override init()
  {
  
  }
  
  //construct with @name, @address, @latitude, and @longitude parameters
  
  init(DesenNo: String, Dolar: String, Zemin: String, En: String, Euro: String, Renk: String) {
  
      self.DesenNo = DesenNo
      self.Dolar = Dolar
      self.Zemin = Zemin
      self.En = En
      self.Euro = Euro
      self.Renk = Renk
  
  
  }
  
  
  //prints object's current state
  
  override var description: String {
      return "Desen: \(DesenNo), Dolar: \(Dolar), Zemin: \(Zemin), Renk: \(Renk), En: \(En), Euro: \(Euro) "
  
  }
  </code></pre>
  
  <p>}</p>
  
  <p>HomeModel.Swift</p>
  
  <p>import UIKit</p>
  
  <p>protocol HomeModelProtocol: class {
      func itemsDownloaded(items: NSArray)
  }</p>
  
  <p>class HomeModel: NSObject {</p>
  
  <pre><code>//properties
  
  weak var delegate: HomeModelProtocol!
  
  let urlPath = "http://aktul.com/den.php" //this will be changed to the path where service.php lives
  
  func downloadItems() {
  
      let url: URL = URL(string: urlPath)!
      let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
  
      let task = defaultSession.dataTask(with: url) { (data, response, error) in
  
          if error != nil {
              print("Failed to download data")
          }else {
              print("Data downloaded")
              self.parseJSON(data!)
          }
  
      }
  
      task.resume()
  }
  
  func parseJSON(_ data:Data) {
  
      var jsonResult = NSArray()
  
      do{
          jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
  
      } catch let error as NSError {
          print(error)
  
      }
  
      var jsonElement = NSDictionary()
      let urunler = NSMutableArray()
  
      for i in 0 ..&lt; jsonResult.count
      {
  
          jsonElement = jsonResult[i] as! NSDictionary
  
          let urun = LocationModel()
  
          //the following insures none of the JsonElement values are nil through optional binding
          if let desen = jsonElement["DesenNo"] as? String,
              let dolar = jsonElement["Dolar"] as? String,
              let zemin = jsonElement["Zemin"] as? String,
              let renk = jsonElement["Renk"] as? String,
              let en = jsonElement["En"] as? String,
              let euro = jsonElement["Euro"] as? String
  
  
              //let longitude = jsonElement["Longitude"] as? String
          {
  
              urun.DesenNo = desen
              urun.Dolar = dolar
              urun.Zemin = zemin
              urun.Renk = renk
              urun.En = en
              urun.Euro = euro
          }
  
          urunler.add(urun)
      }
  
  
      DispatchQueue.main.async(execute: { () -&gt; Void in
  
          self.delegate.itemsDownloaded(items: urunler)
      })
  }
  </code></pre>
  
  <p>}</p>