Search code examples
jsonswiftuipickerview

Swift: Json parse in two pickerView between country and city


I have two JSON Url. want to parse between two UIPickerView. one UIPickerView for Country, and another one for the city. I have been able to parse JSON in first UIPickerView of Country, in here data is coming perfectly. but I got a thread message in DidSelectRow func when clicking UIPickerView of the city. please try to solve this problem

here is my code.

var arrCountryPicker = [CountryPicker]()

 var arrCitiPicker = [CityPicker]()

    var id = 0
    var country_id = 0

my two URL

let url = URL(string: "http://......./mobile-app/countries")

let url = URL(string: "http://......../mobile-app/city-by-country-id?country_id="+String(country_id))

PickerViewCode

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {


    var country: Int = arrCountryPicker.count

    if pickerView == cityPickerView {

        country = self.arrCitiPicker.count
    }
    return country
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

    if pickerView == countryPickerView {

        let titleRow = arrCountryPicker[row].name

        return titleRow

    } else if pickerView == cityPickerView{
        let titleRow = arrCitiPicker[row].name

        return titleRow
    }
    return ""
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

    countryTextField.text = arrCountryPicker[row].name

    if pickerView == countryPickerView {
        self.countryTextField.text = self.arrCountryPicker[row].name
        self.country_id = self.arrCountryPicker[row].id!
        self.countryPickerView.isHidden = true
    }
    else if pickerView == cityPickerView{

Thread about down code is "Thread 1: exc_bad_instruction(code=exc_1386_invop,subcode=0x0)

        self.cityTextField.text = self.arrCitiPicker[row].name

        self.cityPickerView.isHidden = true

    }
    self.view.endEditing(true)
}


func textFieldDidBeginEditing(_ textField: UITextField) {

    if (textField == countryTextField){
        self.countryPickerView.isHidden = false

    }
    else if (textField == cityTextField){
        self.cityPickerView.isHidden = false

    }

}

Solution

  • You need to update array of city picker whenever you change Country.

    In did select of Country picker, Call web service for particular country id and update array of Cities.

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    
        //Remove this line
        //txtCountry.text = self.arrCountries[row].name
    
        if pickerView == CountryPicker {
            self.txtCountry.text = self.arrCountries[row].name
            self.country_id = self.arrCountryPicker[row].id!
    
            //Update city array according selected country
            self.updateCitiesFor(id: row)
    
            self.CountryPicker.isHidden = true
        }  else if pickerView == cityPicker {
            self.txtCity.text = self.arrCities[row].name
            self.cityPicker.isHidden = true
        }
        self.view.endEditing(true)
    }
    

    func for update arrCitiPicker

    func updateCitiesFor(id: Int) {
    
        let url = URL(string: "http://......../mobile-app/\(id)")
    
        //Call web service and store cities data of selected country into arrCitiPicker
    
        //Clear city textfield when country change
        self.txtCity.text = ""     
    
        //Update City Picker with new data
        cityPicker.reloadAllComponents()
    }