I have two NSCombobox in same ViewController. One is for country and other for city. I have text files with country name which includes cities with respective latitude and longitude. For example: USA text file contains 17456 list of cities. I want to populate cities with respect to their country name. But combobox freezes while loading large number of cities. Especially, while searching cities in combobox application freezes due to large memory consumption. My text file looks like this:
214 North Temple Condominium,UT,Salt Lake,40N46'19,111W54'01,1,4265,L
A and B Trailer Court Number One,MT,Hill,48N33'09,109W40'50,1,,
A and B Trailer Court Number Two,MT,Hill,48N33'00,109W41'00,1,,
This is what i have tried.
let countryList = ["USA","Germany","Canada","Finland"]
var citiesList: [String] = []
var counter = 0
var countryOrCities = ""
@IBOutlet var country: NSComboBox!
@IBOutlet var city: NSComboBox!
override func viewDidLoad() {
super.viewDidLoad()
country.usesDataSource = true
country.dataSource = self
city.usesDataSource = true
city.dataSource = self
country.stringValue = "USA"
citiesList = readCitiesFromCountry(country: "USA")
}
func readCitiesFromCountry(country: String) -> [String] {
var flag = true
var returnedCitiesList: [String] = []
if let path = Bundle.main.path(forResource: country, ofType: "txt") {
guard let streamReader = StreamReader(path: path) else {fatalError()}
defer {
streamReader.close()
}
while flag {
if let nextLine = streamReader.nextLine() {
returnedCitiesList.append(nextLine)
} else {
flag = false
}
}
} else {
fatalError()
}
return returnedCitiesList
}
func numberOfItems(in comboBox: NSComboBox) -> Int {
switch comboBox {
case country:
counter = countryList.count
case city:
counter = citiesList.count
default:
break
}
return counter
}
func comboBox(_ comboBox: NSComboBox, objectValueForItemAt index: Int) -> Any? {
switch comboBox {
case country:
countryOrCities = countryList[index]
case city:
countryOrCities = citiesList[index]
default:
break
}
return countryOrCities
}
func comboBoxSelectionDidChange(_ notification: Notification) {
let comboBox = (notification.object as? NSComboBox)!
if comboBox == country {
citiesList = readCitiesFromCountry(country: country.stringValue)
city.reloadData()
} else {
print("Value changed by other")
}
}
Instead of dropDownSize to be specific number, i want it to read all the number of cities so that searching cities for selected country is not restricted. StreamReader class is from Read a file/URL line-by-line in Swift
What i am trying to achieve is like this https://www.youtube.com/watch?v=QrdA-zbW4_o&feature=youtu.be>