ios - Json 数据的 Tableview SearchBar

标签 ios json swift uisearchbar searchbar

我正在制作一个解析 JSON 数据并填充表格 View 的应用程序。在此应用程序中,我想创建一个搜索栏来搜索 id。解析和填充表格 View 一切都很好,但我在搜索时遇到问题。当我运行应用程序时,出现以下错误:因 NSException 类型的未捕获异常而终止

我有两个数组,第一个是主数组,另一个是过滤数组。

要求:我想通过我在模型中声明的“DesenNo”搜索数组。

这是我的代码:

View Controller :

导入UIKit 进口基金会 导入os.log

ViewController 类:UIViewController、UITableViewDataSource、UITableViewDelegate、UISearchResultsUpdating、HomeModelProtocol {

//Properties
var feedItems: NSArray = NSArray()
var detailViewController: detailsVC? = nil
var searchActive : Bool = false
var filteredData:[String] = []
    var resultSearchController:UISearchController!
@IBOutlet weak var listTableView: UITableView!

@IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
    super.viewDidLoad()

    resultSearchController = UISearchController(searchResultsController: nil)

    resultSearchController.searchResultsUpdater = self

    resultSearchController.hidesNavigationBarDuringPresentation = false

    resultSearchController.dimsBackgroundDuringPresentation = false

    resultSearchController.searchBar.searchBarStyle = UISearchBarStyle.prominent

    resultSearchController.searchBar.sizeToFit()

    self.listTableView.tableHeaderView = resultSearchController.searchBar

    self.listTableView.dataSource = self

    let homeModel = HomeModel()
    homeModel.delegate = self
    homeModel.downloadItems()

}


func itemsDownloaded(items: NSArray) {

    feedItems = items
    self.listTableView.reloadData()
}


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

    if resultSearchController.isActive {
        return filteredData.count
    }
    else {
        return feedItems.count
    }

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Retrieve cell

    let cellIdentifier: String = "BasicCell"
    let myCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! MyTableCell
    // Get the location to be shown
    // Get references to labels of cell
     //Label1
    if resultSearchController.isActive {
        let item: LocationModel = feedItems[indexPath.row] as! LocationModel
        let desenNoToString = item.DesenNo

        let desenString = "\(desenNoToString)"
        let regex = try! NSRegularExpression(pattern:"\"(.*)\"")
        if let match = regex.firstMatch(
            in: desenString, range:NSMakeRange(0,desenString.utf16.count)) {
            let result = (desenString as NSString).substring(with: match.range(at:1))
            myCell.label1!.text = result
        }


        //Label2
        let dolarToString = item.Dolar
        let dolarString = "\(dolarToString)"
        if let match = regex.firstMatch(
            in: dolarString, range:NSMakeRange(0,dolarString.utf16.count)) {
            let result = (dolarString as NSString).substring(with: match.range(at:1))
            myCell.label2!.text = result
        }

        //Label3
        let zeminToString = item.Zemin
        let zeminString = "\(zeminToString)"
        if let match = regex.firstMatch(
            in: zeminString, range:NSMakeRange(0,zeminString.utf16.count)) {
            let result = (zeminString as NSString).substring(with: match.range(at:1))
            myCell.label3!.text = result
        }

        //Label4
        let renkToString = item.Renk
        let renkString = "\(renkToString)"
        if let match = regex.firstMatch(
            in: renkString, range:NSMakeRange(0,renkString.utf16.count)) {
            let result = (renkString as NSString).substring(with: match.range(at:1))
            myCell.label4!.text = result
        }

        //Label5
        let enToString = item.En
        let enString = "\(enToString)"
        if let match = regex.firstMatch(
            in: enString, range:NSMakeRange(0,enString.utf16.count)) {
            let result = (enString as NSString).substring(with: match.range(at:1))
            myCell.label5!.text = result
        }

        //Label6
        let euroToString = item.Euro
        let euroString = "\(euroToString)"
        if let match = regex.firstMatch(
            in: euroString, range:NSMakeRange(0,euroString.utf16.count)) {
            let result = (euroString as NSString).substring(with: match.range(at:1))
            myCell.label6!.text = result
        }
    }else {
        let item: LocationModel = feedItems[indexPath.row] as! LocationModel
        let desenNoToString = item.DesenNo

        let desenString = "\(desenNoToString)"
        let regex = try! NSRegularExpression(pattern:"\"(.*)\"")
        if let match = regex.firstMatch(
            in: desenString, range:NSMakeRange(0,desenString.utf16.count)) {
            let result = (desenString as NSString).substring(with: match.range(at:1))
            myCell.label1!.text = result
        }


        //Label2
        let dolarToString = item.Dolar
        let dolarString = "\(dolarToString)"
        if let match = regex.firstMatch(
            in: dolarString, range:NSMakeRange(0,dolarString.utf16.count)) {
            let result = (dolarString as NSString).substring(with: match.range(at:1))
            myCell.label2!.text = result
        }

        //Label3
        let zeminToString = item.Zemin
        let zeminString = "\(zeminToString)"
        if let match = regex.firstMatch(
            in: zeminString, range:NSMakeRange(0,zeminString.utf16.count)) {
            let result = (zeminString as NSString).substring(with: match.range(at:1))
            myCell.label3!.text = result
        }

        //Label4
        let renkToString = item.Renk
        let renkString = "\(renkToString)"
        if let match = regex.firstMatch(
            in: renkString, range:NSMakeRange(0,renkString.utf16.count)) {
            let result = (renkString as NSString).substring(with: match.range(at:1))
            myCell.label4!.text = result
        }

        //Label5
        let enToString = item.En
        let enString = "\(enToString)"
        if let match = regex.firstMatch(
            in: enString, range:NSMakeRange(0,enString.utf16.count)) {
            let result = (enString as NSString).substring(with: match.range(at:1))
            myCell.label5!.text = result
        }

        //Label6
        let euroToString = item.Euro
        let euroString = "\(euroToString)"
        if let match = regex.firstMatch(
            in: euroString, range:NSMakeRange(0,euroString.utf16.count)) {
            let result = (euroString as NSString).substring(with: match.range(at:1))
            myCell.label6!.text = result
        }
    }


    return myCell
}
func updateSearchResults(for searchController: UISearchController) {

    if searchController.isActive {

        filteredData.removeAll(keepingCapacity: false)
        let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
        let array = (feedItems as NSArray).filtered(using: searchPredicate)
        filteredData = array as! [String]
        listTableView.reloadData()

    }
    else {

        filteredData.removeAll(keepingCapacity: false)

        filteredData = feedItems as! [String]

        listTableView.reloadData()

    }


}

}

LocationModel.Swift

导入UIKit

类位置模型:NSObject {

//properties

var DesenNo: String?
var Dolar: String?
var Zemin: String?
var En: String?
var Euro: String?
var Renk: String?




//empty constructor

override init()
{

}

//construct with @name, @address, @latitude, and @longitude parameters

init(DesenNo: String, Dolar: String, Zemin: String, En: String, Euro: String, Renk: String) {

    self.DesenNo = DesenNo
    self.Dolar = Dolar
    self.Zemin = Zemin
    self.En = En
    self.Euro = Euro
    self.Renk = Renk


}


//prints object's current state

override var description: String {
    return "Desen: \(DesenNo), Dolar: \(Dolar), Zemin: \(Zemin), Renk: \(Renk), En: \(En), Euro: \(Euro) "

}

}

HomeModel.Swift

导入UIKit

协议(protocol) HomeModelProtocol: 类 { func itemsDownloaded(items: NSArray) }

HomeModel 类:NSObject {

//properties

weak var delegate: HomeModelProtocol!

let urlPath = "http://aktul.com/den.php" //this will be changed to the path where service.php lives

func downloadItems() {

    let url: URL = URL(string: urlPath)!
    let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)

    let task = defaultSession.dataTask(with: url) { (data, response, error) in

        if error != nil {
            print("Failed to download data")
        }else {
            print("Data downloaded")
            self.parseJSON(data!)
        }

    }

    task.resume()
}

func parseJSON(_ data:Data) {

    var jsonResult = NSArray()

    do{
        jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray

    } catch let error as NSError {
        print(error)

    }

    var jsonElement = NSDictionary()
    let urunler = NSMutableArray()

    for i in 0 ..< jsonResult.count
    {

        jsonElement = jsonResult[i] as! NSDictionary

        let urun = LocationModel()

        //the following insures none of the JsonElement values are nil through optional binding
        if let desen = jsonElement["DesenNo"] as? String,
            let dolar = jsonElement["Dolar"] as? String,
            let zemin = jsonElement["Zemin"] as? String,
            let renk = jsonElement["Renk"] as? String,
            let en = jsonElement["En"] as? String,
            let euro = jsonElement["Euro"] as? String


            //let longitude = jsonElement["Longitude"] as? String
        {

            urun.DesenNo = desen
            urun.Dolar = dolar
            urun.Zemin = zemin
            urun.Renk = renk
            urun.En = en
            urun.Euro = euro
        }

        urunler.add(urun)
    }


    DispatchQueue.main.async(execute: { () -> Void in

        self.delegate.itemsDownloaded(items: urunler)
    })
}

}

最佳答案

updatesearchResults 函数中使用以下代码进行更新

func updateSearchResults(for searchController: UISearchController) {

        if searchController.isActive {

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

            let array = self.feedItems.filter { searchPredicate.evaluate(with: ($0 as! LocationModel).DesenNo) }

            let filterArray = array.map {($0 as! LocationModel).DesenNo}
            filteredData = filterArray as! [String]
            tabelView.reloadData()

        }
        else {
            filteredData.removeAll(keepingCapacity: false)
            tabelView.reloadData()
        }
    }

关于ios - Json 数据的 Tableview SearchBar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49079432/

相关文章:

ios - 在 View Controller 之间传递核心数据项

从后台打开应用程序时,iOS swift 3 重新加载 tableview

ios - swift - 如何设置另一个类的 UIStepper 值?

ios - Swift-无论哪个ViewController启动,在应用启动时都显示showingSplashView

objective-c - AVCaptureVideoPreviewLayer 在简历上不显示任何内容

ios - 无法推断通用参数 'T' - 泛型问题

php - 遍历json数组并插入mysql php

javascript - 仅当从 angularJS 中的 ajax 调用完全接收到 json 时才更新 View

javascript - 在 for 循环中访问 javascript 对象会返回未定义

swift - Swift会使用filter、map、reduce而不是使用for循环来进行一些性能优化吗?