Swift中基于波斯语字符对Bundle内JSON文件排序的实现方法
citname Field in Swift JSON Models for PickerView Hey there! Absolutely, you can sort your parsed city models by the Persian citname field using Swift code—great job getting the parsing started already. Let’s walk through how to do this properly, including handling Persian language sorting and saving the sorted results for later use.
First, Let’s Clean Up the Parsing (Optional but Recommended)
Your current parsing uses JSONSerialization, which works, but using Swift’s Codable will make your code cleaner and less error-prone. Here’s how to refactor that:
- Define Codable models for your JSON structure:
struct City: Codable { let id: Int let citproidint: Int let citname: String // Map JSON's "_id" key to our model's "id" property enum CodingKeys: String, CodingKey { case id = "_id" case citproidint, citname } } struct CityResponse: Codable { let data: [City] }
- Parse the JSON file with
JSONDecoder:
var cityFinalModal: [City] = [] guard let jsonURL = Bundle.main.url(forResource: "citybig", withExtension: "json") else { print("Oops, couldn't find the city JSON file in the bundle!") return } do { let jsonData = try Data(contentsOf: jsonURL) let cityResponse = try JSONDecoder().decode(CityResponse.self, from: jsonData) cityFinalModal = cityResponse.data } catch { print("Failed to parse JSON: \(error.localizedDescription)") }
Sort by Persian citname
The key here is using localized sorting—regular string comparison won’t handle Persian characters correctly. We’ll use a Persian locale to ensure the sort order matches Persian language rules:
// Create a Persian locale for accurate sorting let persianLocale = Locale(identifier: "fa_IR") // Sort the city array cityFinalModal.sort { cityA, cityB in // Use localizedStandardCompare for natural, locale-aware sorting return cityA.citname.localizedStandardCompare(cityB.citname, locale: persianLocale) == .orderedAscending }
This will sort your cities correctly by their Persian citname values, just like you need for the PickerView.
Save the Sorted Results
To avoid re-parsing and re-sorting every time your app launches, save the sorted array to UserDefaults:
// Save sorted cities to UserDefaults do { let encodedCities = try JSONEncoder().encode(cityFinalModal) UserDefaults.standard.set(encodedCities, forKey: "SortedPersianCities") } catch { print("Failed to save sorted cities: \(error.localizedDescription)") } // Load saved sorted cities later (e.g., in viewDidLoad) if let savedCitiesData = UserDefaults.standard.data(forKey: "SortedPersianCities") { do { cityFinalModal = try JSONDecoder().decode([City].self, from: savedCitiesData) } catch { print("Failed to load saved cities—falling back to parsing from bundle") // Re-run the initial parsing code here if needed } }
Use the Sorted Array in PickerView
Now you can use cityFinalModal directly as your PickerView’s data source:
// PickerView Data Source Methods func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return cityFinalModal.count } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return cityFinalModal[row].citname }
That’s it! Your PickerView will now display cities sorted by their Persian names, and you won’t have to re-sort them every time the app opens.
内容的提问来源于stack exchange,提问作者Mohammad Reza Koohkan

