Search code examples
iosswiftuitableviewuisearchcontrollerswifty-json

Swift: Filter SwiftyJSON data in tableView


I have data in JSON. I'm working with SwiftyJSON. My data is look like this:

[{
    "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
}]

How to display it on tableView and filter it using UISearchController. Here is my code:

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

It got error like this: 'Value' (aka 'AnyObject') cannot be constructed because it has no accessible initializers

Here is link to github for this question https://github.com/lamfete/MapSearchDemo


Solution

  • I want to answer my own question.

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