arrays - 如何在 Swift 中正确解析带有根元素的 JSON 作为数组?
问题描述
我有以下问题,我没有正确的结构来解码来自 node-red 的响应以了解我的 Sonos 播放器的状态:
[[{"urlHostname":"192.168.1.1","urlPort":1400,"baseUrl":"http://192.168.1.1:1400","sonosName":"Sonos1","uuid":"RINCON_SONOS14001400","invisible":false},{"urlHostname":"192.168.1.2","urlPort":"1400","baseUrl":"http://192.168.1.2:1400","sonosName":"Sonos2","uuid":"RINCON_SONOS21400","invisible":false},{"urlHostname":"192.168.1.3","urlPort":"1400","baseUrl":"http://192.168.1.3:1400","sonosName":"Sonos3","uuid":"RINCON_SONOS31400","invisible":false},{"urlHostname":"192.168.1.4","urlPort":"1400","baseUrl":"http://192.168.1.4:1400","sonosName":"Sonos4","uuid":"RINCON_SONOS41400","invisible":false},{"urlHostname":"192.168.1.5","urlPort":"1400","baseUrl":"http://192.168.1.5:1400","sonosName":"Sonos5","uuid":"RINCON_SONOS51400","invisible":false},{"urlHostname":"192.168.1.6","urlPort":"1400","baseUrl":"http://192.168.1.6:1400","sonosName":"Sonos6","uuid":"RINCON_SONOS61400","invisible":false}]]
我的结构和解码调用如下所示:
typealias Response = [sonosData]
struct sonosData: Codable {
let sonos: [sonosStatusEntry]?
}
struct sonosStatusEntry: Codable {
let status: [sonosStatus]?
}
struct sonosStatus: Codable {
let urlHostname: String
let urlPort: Int
let baseUrl: String
let sonosName: String
let uuid: String
let invisible: Bool
}
let response = try JSONDecoder().decode(Response.self, from: data)
我在 Swift 中收到以下错误:
Failed to load: The data couldn’t be read because it isn’t in the correct format.
有什么建议么?
解决方案
问题之一与urlPort
. 您的 json 具有Int
和String
的值urlPort
。您可以定义自定义初始化来处理它。
struct sonosStatus: Codable {
let urlHostname: String
let urlPort: Int
let baseUrl: String
let sonosName: String
let uuid: String
let invisible: Bool
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
urlHostname = try values.decode(String.self, forKey: .urlHostname)
baseUrl = try values.decode(String.self, forKey: .baseUrl)
sonosName = try values.decode(String.self, forKey: .sonosName)
uuid = try values.decode(String.self, forKey: .uuid)
invisible = try values.decode(Bool.self, forKey: .invisible)
// you can define urlPort as optional or unwrap it.
if let intVal = try? values.decode(Int.self, forKey: .urlPort) {
urlPort = intVal
} else if let stringVal = try? values.decode(String.self, forKey: .urlPort) {
urlPort = Int(stringVal) ?? 0
} else {
urlPort = ""
}
}
}
而且你的 json 是一个数组sonosStatus
数组。
所以你需要修改Response
typealias,如下所示:
typealias Response = [[sonosStatus]]
推荐阅读
- jmeter - JMeter PerfMon 有问题
- python - 在我的 core/urls.py 文件中找不到 Django 页面 (404)。仅在重新排列 url 时有效
- azure - 无法将 Azure 搜索添加到 SQL 数据库
- c# - 如何使用 C sharp 在注册表编辑器中设置现有键
- javascript - ASP.NET Core MVC 控制器从 ajax 调用接收输入参数的 null
- javascript - “阅读更多”影响多个盒子 - 如何更改它?(jQuery/JS/CSS)
- r - 在 Fasterize 中选择多个属性?
- azure-active-directory - 如何使用 Microsoft Graph API 根据页码进行分页
- java - 如何扫描 postgreSQL 中的所有数据库?
- navigation - 如何在 Odoo 13 中隐藏“导航菜单”?