Reputation: 1015
I have a UIPickerView that gets data from JSON and presents it in two columns, one that shows two columns, producer and product using the following:
if let url = URL(string: "https://www.example.com/example"),
let data = try? Data(contentsOf: url),
let tmpValues = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [[String:String]] {
let tempCategories = tmpValues?.reduce(into: [String:[String]](), { (dict, value) in
if let producer = value["producer"], let product = value["product"] {
dict[producer, default:[]].append(product)
}
})
for category in (tempCategories ?? [:]) {
allCategories.append(Category(name: category.key, items: category.value))
}
pickerView.reloadAllComponents()
}
The issue is while the JSON presents the array in alphabetical order, the PickerView presents the array in random orders every time it is opened, how can this be fixed.
Upvotes: 0
Views: 81
Reputation: 81
So, before calling:
pickerView.reloadAllComponents()
you can just sort the array
allCategories = allCategories.sorted { $0.name < $1.name }
and it will solve you issue
Upvotes: 1
Reputation: 285190
First of all you are strongly discouraged from loading data from a remote URL with synchronous Data(contentsOf
. From the documentation
Important
Don't use this synchronous initializer to request network-based URLs. For network-based URLs, this method can block the current thread for tens of seconds on a slow network, resulting in a poor user experience, and in iOS, may cause your app to be terminated.
Instead, for non-file URLs, consider using the
dataTask(with:completionHandler:
) method of theURLSession
class. See Fetching Website Data into Memory for an example.
Secondly, a dictionary is unordered. You could sort the keys and populate the picker source array this way
if let categories = tempCategories {
let sortedKeys = categories.keys.sorted()
allCategories = sortedKeys.map{ Category(name: $0, items: categories[$0]!) }
}
Upvotes: 1