我正在编写一个从Timezonedb API中提取数据以获取可用时区列表的应用程序:
https://timezonedb.com/references/list-time-zone
我正在尝试解析当前格式化为“欧洲/安道尔”的zoneName。我的问题是如何将JSON字符串拆分为仅在表格视图中显示城市名称(即“安道尔”)?
这是我得到的回复:
{
"status":"OK",
"message":"",
"zones":[
{
"countryCode":"AD",
"countryName":"Andorra",
"zoneName":"Europe\/Andorra",
"gmtOffset":7200,
"timestamp":1464453737
},
{
"countryCode":"AE",
"countryName":"United Arab Emirates",
"zoneName":"Asia\/Dubai",
"gmtOffset":14400,
"timestamp":1464460937
},
{"
countryCode":"AF",
"countryName":"Afghanistan",
"zoneName":"Asia\/Kabul",
"gmtOffset":16200,
"timestamp":1464462737
}]}
这是我的代码:
型号:
struct TimeZones: Codable {
let status, message: String?
let zones: [Zone]?
}
struct Zone: Codable {
let countryCode, countryName, zoneName: String?
let gmtOffset, timestamp: Int?
}
这是网络代码:
var cities: [Zone] = []
func getAvailableTimeZones() {
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let url = Bundle.main.url(forResource: "data", withExtension: "json")!
let task = session.dataTask(with: url) { data, response, error in
// Check for errors
guard error == nil else {
print ("error: \(error!)")
return
}
// Check that data has been returned
guard let content = data else {
print("No data")
return
}
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let timeZones = try decoder.decode(TimeZones.self, from: content)
if let zones = timeZones.zones {
self.cities.append(contentsOf: zones)
}
} catch let err {
print("Err", err)
}
}
// Execute the HTTP request
task.resume()
}
TableViewController:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "searchResultsCell", for: indexPath)
cell.textLabel?.text = cities[indexPath.row].zoneName
return cell
}
任何帮助表示赞赏。谢谢。
答案 0 :(得分:3)
一种解决方案是添加CodingKeys
和一个计算属性。
并且没有理由将结构成员声明为可选
struct TimeZones: Decodable {
let status, message: String
let zones: [Zone]
}
struct Zone: Decodable {
let countryCode, countryName, zoneName: String
let gmtOffset, timestamp: Int
private enum CodingKeys: String, CodingKey { case countryCode, countryName, zoneName, gmtOffset, timestamp}
lazy var zoneCountry : String = {
return zoneName.components(separatedBy: "/").last!
}()
}
并使用它
cell.textLabel?.text = cities[indexPath.row].zoneCountry
答案 1 :(得分:0)
要以最小的变化获得所需的输出,只需更新cellForRowAt()方法,如下所示:
let zoneName = cities[indexPath.row].zoneName.components(separatedBy: "/").last ?? ""
cell.textLabel?.text = zoneName