Swift:在 tableView 中过滤 SwiftyJSON 数据

Posted

技术标签:

【中文标题】Swift:在 tableView 中过滤 SwiftyJSON 数据【英文标题】:Swift: Filter SwiftyJSON data in tableView 【发布时间】:2016-07-29 04:19:09 【问题描述】:

我有 JSON 格式的数据。我正在使用 SwiftyJSON。我的数据是这样的:

[
    "kode_customer": 1,
    "nama_customer": "Logam Jaya, UD",
    "alamat_customer": "Rajawali No 95",
    "kodepos": 60176,
    "kode_provinsi": 11,
    "gps_lat": -7.233834999999999,
    "gps_long": 112.72964666666667
, 
    "kode_customer": 2,
    "nama_customer": "Terang, TK",
    "alamat_customer": "Raya Dukuh Kupang 100",
    "kodepos": 60225,
    "kode_provinsi": 11,
    "gps_lat": -7.285430000000001,
    "gps_long": 112.71538333333335
, 
    "kode_customer": 3,
    "nama_customer": "Sinar Family",
    "alamat_customer": "By Pass Jomin No 295",
    "kodepos": 41374,
    "kode_provinsi": 9,
    "gps_lat": -6.4220273,
    "gps_long": 107.4748978
, 
    "kode_customer": 4,
    "nama_customer": "Lancar Laksana, TB",
    "alamat_customer": "Jendral Sudirman No 69",
    "kodepos": 41374,
    "kode_provinsi": 9,
    "gps_lat": -6.4220273,
    "gps_long": 107.4748978
]

如何在tableView 上显示它并使用UISearchController 过滤它。这是我的代码:

class LocationSearchTable: UITableViewController 

    var custData: JSON = []   
    var filteredData: [String]!

    func getCustData() 
        let path = NSBundle.mainBundle().pathForResource("cust_toko", ofType: "json")
        let jsonData = NSData(contentsOfFile: path!)
        let json = JSON(data: jsonData!)

        self.custData = son
    

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return filteredData.count
    

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCellWithIdentifier("cell")!
        cell.textLabel?.text = filteredData[indexPath.row]
        return cell
    

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
        print(filteredData[indexPath.row])
    


extension LocationSearchTable: UISearchResultsUpdating 
    func updateSearchResultsForSearchController(searchController: UISearchController) 
        if let searchText = searchController.searchBar.text 
            let searchPredicate = NSPredicate(format: "name contains[cd] %@", searchText)
            filteredData = JSON(custData.filter JSON.Value() )

            tableView.reloadData()
        
    

出现这样的错误:'Value' (aka 'AnyObject') cannot be constructed because it has no accessible initializers

这里是这个问题的 github 链接https://github.com/lamfete/MapSearchDemo

【问题讨论】:

【参考方案1】:

首先您需要使用arrayObject 从JSON 对象中获取数组,然后您需要将谓词键name 更改为customer_name,因为您的json 响应中没有key 名称,因此请更改您的代码像这样只从该结果中获取 customer_name。

extension LocationSearchTable: UISearchResultsUpdating 
    func updateSearchResultsForSearchController(searchController: UISearchController) 
        if let searchText = searchController.searchBar.text 
            let searchPredicate = NSPredicate(format: "nama_customer contains[cd] %@", searchText)
            if let array = custData.arrayObject as? [[String:AnyObject]] 
                 let filterArr = array.filter searchPredicate.evaluateWithObject($0) 
                 filteredData = filterArr.map( String($0["nama_customer"]))
                 tableView.reloadData()
            
        
    

【讨论】:

嗨,它有 2 个错误。第一个错误是'Value' (aka 'AnyObject') cannot be constructed because it has no accessible initializers on let filterArr = JSON(custData.filter JSON.Value() ),第二个错误是Use of unresolved identifier 'filterData' on filterData = filterArr.map $0["nama_customer"] 错误Cannot convert value of type 'Element' (aka '(String, JSON)') to expected argument type 'AnyObject?' 发生在let filterArr = JSON(custData.filter searchPredicate.evaluateWithObject($0) ) 指向$0 仍然错误,先生 Type 'Element' (aka '(String, JSON)') has no subscript members on 'filteredData = filterArr.map $0["nama_customer"] ' 我在 ["nama_customer"] 之后添加了 .stringValue 但仍然有错误。 编译时间,先生。错误是Type 'Element' (aka '(String, JSON)') has no subscript members 检查我的编辑,我已更改if let array = custData.arrayObject as? [[String:AnyObject]] 【参考方案2】:

我想回答我自己的问题。

import Foundation
import UIKit
import SwiftyJSON
import MapKit

class LocationSearchTable: UITableViewController 

    var custData: JSON = []
    var dbTokos : [Toko] = []
    var filteredDataToko: [Toko]!

    var handleMapSearchDelegate: HandleMapSearch? = nil
    var vc = ViewController()

    func getCustData() 
        let path = NSBundle.mainBundle().pathForResource("cust_toko", ofType: "json")
        let jsonData = NSData(contentsOfFile: path!)
        let json = JSON(data: jsonData!)

        self.custData = Jon

        splitData()


    func splitData() 
        for(_, subJson):(String, JSON) in self.custData 
            if let name: String = subJson["nama_customer"].stringValue 
                if let address: String = subJson["alamat_customer"].stringValue 
                    if let city: String = subJson["kota"].stringValue 
                        if let province: String = subJson["provinsi"].stringValue 
                            if let lat: Double = subJson["gps_lat"].doubleValue 
                                if let long: Double = subJson["gps_long"].doubleValue 
                                    let toko = Toko(title: name,
                                                locationName: address,
                                                cityName: city,
                                                provinsiName: province,
                                                coordinate: CLLocationCoordinate2D(latitude: lat, longitude: long))
                                    dbTokos.append(toko)
                                
                            
                        
                    
                
            
        
    

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return filteredDataToko.count
    

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCellWithIdentifier("cell")!
        cell.textLabel!.text = String(filteredDataToko[indexPath.row].title!)
        cell.detailTextLabel!.text = String(filteredDataToko[indexPath.row].locationName) + ", " + String(filteredDataToko[indexPath.row].cityName) + ", " + String(filteredDataToko[indexPath.row].provinsiName)
        return cell
    

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 

        let toko = Toko(title: filteredDataToko[indexPath.row].title!,
                        locationName: filteredDataToko[indexPath.row].locationName,
                        cityName: filteredDataToko[indexPath.row].cityName,
                        provinsiName: filteredDataToko[indexPath.row].provinsiName,
                        coordinate: filteredDataToko[indexPath.row].coordinate)

        handleMapSearchDelegate?.dropPinZoomIn(toko)
        dismissViewControllerAnimated(true, completion: nil)
    


extension LocationSearchTable: UISearchResultsUpdating 
    func updateSearchResultsForSearchController(searchController: UISearchController) 
        if let searchText = searchController.searchBar.text 
            filteredDataToko = searchText.isEmpty ? dbTokos : dbTokos.filter(
                
                    (dataString: Toko) -> Bool in
                    return dataString.title?.rangeOfString(searchText, options: .CaseInsensitiveSearch) != nil
                
            )
            tableView.reloadData()
        
    

【讨论】:

为什么要从一个字符串中初始化一个字符串(titlelocationName等好像反正是字符串)? 所以它不是可选的

以上是关于Swift:在 tableView 中过滤 SwiftyJSON 数据的主要内容,如果未能解决你的问题,请参考以下文章

iOS Swift didSelectRowAtIndexPath 不起作用

不能使用 Swift 语法过滤器

使用swift3在tableview中搜索栏和部分

同时应用谓词来过滤列表(SWI Prolog)

无法过滤使用字典数组创建的tableview

清除搜索结果后,Swift Tableview 搜索结果单元格选择复选标记未保存