2016-11-30 42 views
1

的搜索欄上點擊時,我得到這個錯誤:「不能在使用/包含運營商,集」

終止應用程序由於未捕獲的異常「NSInvalidArgumentException」,原因:「不能使用in/contains操作符Assignment_4.SearchResult(studentID:「1060」,姓氏:「Squarepants」,名字:「Spongebob」,主要:「Krusty Krab廚師」,年:「Junior」,gpa:「4.0」)(不是集合)'

獲取此行的錯誤。

let array = (results as NSArray).filtered(using: searchPredicate) 

這是整個代碼。我無法弄清楚什麼是錯的。謝謝!!

var results = [SearchResult]() 
var indexN = 0 
var addStudent = false 
var searchController: UISearchController! 

var filteredTableData = [String]() 
var resultSearchController = UISearchController() 


@IBAction func AddStudentButton(_ sender: Any) { 
    addStudent=true 
    performSegue(withIdentifier: "detailSegue", sender: self) 
} 

@IBAction func refreshButton(_ sender: Any) { 
    refreshTable() 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 

    listTableView.delegate = self 
    listTableView.dataSource = self 

    listTableView.reloadData() 

    jsonParser() 

    self.resultSearchController = ({ 

     let controller = UISearchController(searchResultsController: nil) 

     controller.searchResultsUpdater = self 

     controller.dimsBackgroundDuringPresentation = true 

     controller.searchBar.sizeToFit() 



     self.listTableView.tableHeaderView = controller.searchBar 



     return controller 

    })() 
    self.listTableView.reloadData() 


} 

/* 
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return 1 
} 
*/ 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

    if (self.resultSearchController.isActive) { 

     return self.filteredTableData.count 

    } 

    else { 

     return self.results.count 

    } 

    // return self.results.count 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell:UITableViewCell = UITableViewCell(style:UITableViewCellStyle.subtitle, reuseIdentifier: "cell") 
    //cell.textLabel!.text = self.results[indexPath.row].firstName + " " + results[indexPath.row].lastName 
    //return cell 

    // let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 



    if (self.resultSearchController.isActive) { 

     cell.textLabel?.text = filteredTableData[indexPath.row] 



     return cell 

    } 

    else { 

     cell.textLabel?.text = self.results[indexPath.row].firstName + " " + results[indexPath.row].lastName 
     return cell 

    } 

} 

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    indexN = indexPath.row 
    addStudent=false 
    performSegue(withIdentifier: "detailSegue", sender: self) 
} 

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 
    return true 
} 

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
    if (editingStyle == UITableViewCellEditingStyle.delete) { 
     // handle delete (by removing the data from your array and updating the tableview) 
     Delete(studentID: self.results[indexN].studentID) 
     refreshTable() 
    } 
} 

func numberOfSections(in tableView: UITableView) -> Int { 

    return 1 

} 




override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func jsonParser() { 
    let urlPath = "http://csmadison.dhcp.bsu.edu/~vjtanksale/cs320/selectstudents.php" 
    guard let endpoint = URL(string: urlPath) else { 
     print("Error creating endpoint") 
     return 
    } 
    let request = URLRequest(url: endpoint) 
    URLSession.shared.dataTask(with: request) { (data, response, error) in 
     do { 
      guard let data = data else { 
       return 
      } 
      guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [[String:AnyObject]] else { 
       print("No idea") 
       return 
      } 

      for result in json { 
       if let student = SearchResult(json: result) { 
        self.results.append(student) 
       } 
      } 
      self.grabData() 
     } catch let error as NSError { 
      print(error.debugDescription) 
     } 
     }.resume() 
} 

func grabData() { 
    DispatchQueue.main.async { 
     self.listTableView.reloadData() 
    } 
} 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if(addStudent==false){ 
     let newVC: DetailViewController = segue.destination as! DetailViewController 
     newVC.result = results[indexN] 
     newVC._label1 = results[indexN].studentID 
     newVC._label2 = results[indexN].lastName 
     newVC._label3 = results[indexN].firstName 
     newVC._label4 = results[indexN].major 
     newVC._label5 = results[indexN].year 
     newVC._label6 = results[indexN].gpa 
    } 
    else if(addStudent==true){ 
     let newVC: DetailViewController = segue.destination as! DetailViewController 
     newVC.addStudent=true 
    } 

} 

func Delete(studentID: String) { 
    let request = NSMutableURLRequest(url: NSURL(string: "http://csmadison.dhcp.bsu.edu/~vjtanksale/cs320/deletestudents.php")! as URL) 
    request.httpMethod = "POST" 
    let postString = "StudentId="+studentID 
    request.httpBody = postString.data(using: String.Encoding.utf8) 

    let task = URLSession.shared.dataTask(with: request as URLRequest) { 
     data, response, error in 

     if error != nil { 
      print("error=\(error)") 
      return 
     } 

     print("response = \(response)") 

     let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue) 
     print("responseString = \(responseString)") 
    } 
    task.resume() 
} 

func refreshTable(){ 
    results.removeAll() 
    self.listTableView.reloadData() 
    jsonParser() 
    self.listTableView.reloadData() 
} 

func updateSearchResults(for searchController: UISearchController) 

{ 

    filteredTableData.removeAll(keepingCapacity: false) 



    let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!) 

    let array = (results as NSArray).filtered(using: searchPredicate) 

    filteredTableData = array as! [String] 



    self.listTableView.reloadData() 

} 

}

+0

錯誤消息說謂詞無法評估* [SearchResult]包含String *。除此之外,您應該使用本機Swift'filter',而不是使用'NSPredicate'(起訴那些提示的教程)將其轉換爲'NSArray',並且爲數據源數組和過濾數組保持一致的數組類型。 – vadian

回答

3

因爲你試圖用一個CONTAINS謂詞SearchResult對象,這不符合規定的CONTAINS概念集合你收到此錯誤。此錯誤在運行時發生,因爲NSPredicate在運行時分析並處理其字符串。對於這種情況,使用本地快速設施更爲優選:

let searchTerm = searchController.searchBar.text! 

let array = results.filter { result in 
    return result.studentID.contains(searchTerm) || 
      result.something.contains(searchTerm) // and so on... 
} 
+0

嘗試使用此功能時出現錯誤。 – tncb

+0

let array =(result as NSArray).filtered {result in return result.studentID.contains(searchTerm) } – tncb

+0

因爲'filter'(我在我的問題中犯了一個錯字)是Swift的'Array'方法,*而不是*'NSArray'。 – Alexander