我该如何在Swift中拆分JSON字符串?

24 浏览
0 Comments

我该如何在Swift中拆分JSON字符串?

这个问题已经有了答案:

如何在Swift中将字符串分割成数组?

我正在编写一个应用程序,从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
    }]}

这是我的代码:

Model:

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
}

任何帮助将不胜感激。谢谢。

admin 更改状态以发布 2023年5月21日
0
0 Comments

为了用最小的改动获得所需的输出,您只需更新cellForRowAt()方法,如下所示:

let zoneName = cities[indexPath.row].zoneName.components(separatedBy: "/").last ?? ""
cell.textLabel?.text = zoneName

0
0 Comments

一个解决方案是添加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

0