John
John

Reputation: 1015

How to present JSON array in UIPickerView in alphabetical order?

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

Answers (2)

Nick  Burinok
Nick Burinok

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

vadian
vadian

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 the URLSession 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

Related Questions