In an NSArray, I need to filter all elements containing a searchKey (eg 39013). For now, I can print and see the values on Xcode but I want them on my device. I have two arrays. First one is:
var feedItems: NSArray = NSArray()
and the filtered one is
var filteredData:[String] = []
I print the filteredData and everything is as I wanted. Here is the problem I made a mistake on viewController while printing the lines.
if resultSearchController.isActive {
let item: LocationModel = feedItems[indexPath.row] as! LocationModel
I need to change .. = feedItems
to .. = filteredData
But when I change, since the filteredData
is a String Array (Not an NSarray) I get an error:
Cast from 'String' to unrelated type 'LocationModel' always fails
Can you help me to fix the last problem? Thank you so much!!
Following is the Code:
Here is the object:
import UIKit
class LocationModel: NSObject {
//properties
var DesenNo: String?
var Dolar: String?
var Zemin: String?
var En: String?
var Euro: String?
var Renk: String?
}
In Swift 3+ try to avoid (NS)Stuff like NSArray
. Prefers the Swift version when available.
You declared:
var filteredData:[String] = []
So filteredData
will be an array of String
, of ONLY String
objects.
Then you do
let item: LocationModel = filteredData[indexPath.row] as! LocationModel
But you said previously that filteredData
will be an array of String objects. So filteredData[indexPath.row]
should be a String
object. But you are trying to force cast it into a LocationModel
object. The compiler is saying: That's not happening, I can't convert a String
object into a LocationModel
object.
With NSArray
, objects inside are of type Any
. If you declare filteredData
as NSArray
but put inside LocationModel
objects:
let item: LocationModel = filteredDataAsNSArray[indexPath.row] as! LocationModel
That will crash, no doubt about it.
There are still some issues, I think you want ta filteredData being of LocationModel
objects
Do this:
var filteredData:[LocationModel] = []()
var feedItems:[LocationModel] = []()
The filtering: You want to filter on each values of your LocationModel
so the predicate format should be:
(SELF.DesenNo CONTAINS[c] %@) OR (SELF.Dolar CONTAINS[c] %@) OR (SELF.Zemin CONTAINS[c] %@) OR (SELF.En CONTAINS[c] %@) OR (SELF.Euro CONTAINS[c] %@) OR (SELF.Renk CONTAINS[c] %@)
You could also use a Swift filter in pseudo code (not tested):
let textToSearch = searchController.searchBar.text
filteredData = feedItems.filter({$0.DesenNo.lowercased().contains(textToSearch.lowercased()) || $0.DesenNo.lowercased().contains(textToSearch.lowercased()) || ...})
Also in tableView(_ tableView:, cellForRowAt:)
you do the same thing again and again, that could should be factorized and for better clarity put into the MyTableCell
code.
This way you could do something like cell.updateWith(item:item)
and it will be clearer.
Edit:
Last recommendation: Please rename your var starting with a lowercase (DesenNo
=> desenNo
, etc.).