Cannot convert value of type '[Record]' to type 'Record' in coercion

后端 未结 2 639
感动是毒
感动是毒 2021-01-21 09:00

Im re-writing an iOS app I made using C# and Xamarin to Swift for obvious reasons of Xamarin\'s pricing, and low documentation. Following this tutorial for including a UIS

相关标签:
2条回答
  • 2021-01-21 09:38

    Because I think type of your self.records is [Record] and you are trying to casting it as single Record which is not an Array. So it is not possible.

    Try this:

    let array = (self.records as [Record]).filteredArrayUsingPredicate(searchPredicate)
    

    UPDATE:

    Update your updateSearchResultsForSearchController method like this:

    func updateSearchResultsForSearchController(searchController: UISearchController)
    {
        self.filteredRecords.removeAll(keepCapacity: false)
    
    
        self.filteredRecords = self.records.filter() {
            ($0.album.lowercaseString).containsString(searchController.searchBar.text!.lowercaseString)
        }
        self.tableView.reloadData()
    }
    

    If you want to search for both album and artist then replace this line:

    ($0.album.lowercaseString).containsString(searchController.searchBar.text!.lowercaseString)
    

    with this line:

    ($0.album.lowercaseString).containsString(searchController.searchBar.text!.lowercaseString) || ($0.artist.lowercaseString).containsString(searchController.searchBar.text!.lowercaseString)
    
    0 讨论(0)
  • 2021-01-21 09:50

    filteredArrayUsingPredicate is an NSArray method, so you should cast it to NSArray:

    let array = (self.records as NSArray).filteredArrayUsingPredicate(searchPredicate)
    

    But this still generate an error "[Record] is not convertible to NSArray". This is because an NSArray can only contain Objective-C objects, and Record is a Swift struct and is not convertible to an object. There are two solutions.

    Solution 1:

    Declare Record as an object

    class Record: NSObject {
        let album : String
        let artist : String
        let genre : String
        let year : Int
        let speed : String
        let size : Int
    
        init(album : String, artist : String, genre : String, year : Int, speed : String, size : Int) {
            self.album = album
            self.artist = artist
            self.genre = genre
            self.year = year
            self.speed = speed
            self.size = size
        }
    }
    

    Then the following code should works

    let searchPredicate = NSPredicate(format: "SELF.artist CONTAINS [c] %@", searchController.searchBar.text!)
    let array = (self.records as NSArray).filteredArrayUsingPredicate(searchPredicate)
    self.filteredRecords = array as! [Record]
    

    Note your original predicate doesn't make sense, and would cause runtime error, because Record is not a String, so I replace it.

    Solution 2:

    Use the Swift way to filter:

    let searchText = searchController.searchBar.text!.lowercaseString
    filteredRecords = self.records.filter { (aRecord) -> Bool in
        return aRecord.artist.lowercaseString.containsString(searchText)
    }
    
    0 讨论(0)
提交回复
热议问题