Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
142 views
in Technique[技术] by (71.8m points)

uisearchbar - 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.

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)'

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()


    }
}

I have also tired:

let searchPredicate = NSPredicate(format: "fullname CONTAINS[c] %@", searchString as String)

which returns the error:

this class is not key value coding-compliant for the key fullname

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).

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)}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...