搜索栏 Swift 3 - 不能将 in/contains 运算符与集合一起使用 [英] Search Bar Swift 3 - Can't use in/contains operator with collection
问题描述
我正在我的项目中实现一个搜索栏,但出现以下错误.
I am implementing a search bar into my project but I am being presented with the below error.
原因:'不能使用 in/contains 操作符与集合 wellpleased.attendees.UserData(firstname: "Ben", lastname: "Delonge", fullname: "Ben Delonge", company: "AllStar.com", jobtitle:业务发展经理",图片:6.jpg")(不是合集)'
reason: 'Can't use in/contains operator with collection wellpleased.attendees.UserData(firstname: "Ben", lastname: "Delonge", fullname: "Ben Delonge", company: "AllStar.com", jobtitle: "Business Development Manager", image: "6.jpg") (not a collection)'
我已经对 NSPredicate 进行了大量搜索,但似乎无法防止这种崩溃.
I have done plenty of searching around the NSPredicate but cannot seem to prevent this crashing.
我正在使用下面的代码,任何解决此问题的帮助将不胜感激.
I am using the code below, any assistance resolving this would be much appreciated.
class attendees: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
var tableData = ""
var value:String!
var searchString: String = ""
var dataSource: [UserData] = []
struct UserData {
var firstname: String
var lastname: String
var fullname: String
var company: String
var jobtitle: String
var image: String
}
var filteredAppleProducts = [String]()
var resultSearchController = UISearchController()
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
print(value)
searchBar.delegate = self
self.tableView.reloadData()
let nib = UINib(nibName: "vwTblCell2", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "cell2")
}
override func viewDidAppear(_ animated: Bool) {
getTableData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if filteredAppleProducts != []{
return self.filteredAppleProducts.count
}
else
{
if searchString != "[]" {
return self.dataSource.count
}else {
return 0
}
}
}
// 3
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell2: TblCell2 = self.tableView.dequeueReusableCell(withIdentifier: "cell2") as! TblCell2
print(filteredAppleProducts)
if filteredAppleProducts != []{
cell2.nameLabel.text = self.filteredAppleProducts[indexPath.row]
return cell2
}
else
{
if searchString != "[]"{
cell2.nameLabel.text = self.dataSource[indexPath.row].fullname
cell2.companyLabel.text = self.dataSource[indexPath.row].company
cell2.jobTitleLabel.text = self.dataSource[indexPath.row].jobtitle
let url = URL(string: "https://www.asmserver.co.uk/wellpleased/backend/profileimages/\(self.dataSource[indexPath.row].image)")
let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
cell2.userImage.image = UIImage(data: data!)
}
return cell2
}
}
// 4
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
// 5
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 90
}
func updateSearchResults(){
self.filteredAppleProducts.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchString)
let array = (self.dataSource as NSArray).filtered(using: searchPredicate)
self.filteredAppleProducts = array as! [String]
self.tableView.reloadData()
print(filteredAppleProducts)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
print("searchText \(searchText)")
print(filteredAppleProducts)
searchString = searchText
updateSearchResults()
}
func getTableData(){
self.dataSource.removeAll()
let defaults = UserDefaults()
let userid = defaults.string(forKey: "id")
let url = NSURL(string: "https://www.******.co.uk/wellpleased/backend/searchattendees.php?userid=\(userid!)&eventid=\(value!)")
print(url)
let task = URLSession.shared.dataTask(with: url as! URL) { (data, response, error) -> Void in
if let urlContent = data {
do {
if let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: []) as? [[String:AnyObject]] {
var i = 0
while i < jsonResult.count {
self.dataSource.append(UserData(firstname:"\(jsonResult[i]["firstname"]! as! String)", lastname: "\(jsonResult[i]["lastname"]! as! String)", fullname:"\(jsonResult[i]["fullname"]! as! String)", company: "\(jsonResult[i]["company"]! as! String)", jobtitle:"\(jsonResult[i]["jobtitle"]! as! String)", image:"\(jsonResult[i]["image"]! as! String)"))
i = i + 1
}
}
} catch {
print("JSON serialization failed")
}
} else {
print("ERROR FOUND HERE")
}
DispatchQueue.main.async(execute: { () -> Void in
self.tableView.reloadData()
})
self.tableView.isUserInteractionEnabled = true
}
task.resume()
}
}
我也累了:
let searchPredicate = NSPredicate(format: "fullname CONTAINS[c] %@", searchString as String)
返回错误:
该类不符合键全名的键值编码
this class is not key value coding-compliant for the key fullname
推荐答案
NSPredicate 是存在于 Objective-C 世界中的 Cocoa 特性.它永远不会在 UserData 数组上工作,因为 UserData 是一个 Swift 结构体——而 Objective-C 根本看不到 Swift 结构体(即使可以,它当然也看不到类中的任何类型命名空间,因为你的用户数据是).
NSPredicate is a Cocoa feature that lives in the Objective-C world. It's never going to work on an array of UserData because UserData is a Swift struct — and Objective-C cannot see a Swift struct at all (and even if it could, it certainly can't see any type namespaced inside a class, as your UserData is).
如果您只是使用内置的 Swift filter
方法来过滤 dataSource
数组,那么您会很容易做到这一点.例如(如果这是你想要做的):
You would have an easy time of this if you simply used the built-in Swift filter
method to filter the dataSource
array. For example (if this is what you're trying to do):
let array = self.dataSource.filter{$0.fullname.contains(searchString)}
这篇关于搜索栏 Swift 3 - 不能将 in/contains 运算符与集合一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!