使用postman我验证json响应(这些Room
对象的列表)
{
"id": "506e9a1d-cded-4853-a9df-7f8a57d6550d",
"name": "TeleTwo",
"shortName": "2",
"displayName": "2",
"inService": true,
"managed": true,
"capacity": 2,
"schedulingOption": "VC Scheduling",
"location": {
"id": "50b07258-2668-416e-aef4-a8a48e9e7389",
"name": "Telepresence Test",
"shortName": "Telepresence Test",
"displayName": "Telepresence Test",
"city": "Nash",
"country": "United States",
"account": {
"id": "509788c6-197f-40f1-a7f7-274a23af9062",
"name": "Development",
"shortName": "Dev",
"displayName": "Dev",
"active": true,
"exchangeEnabled": false,
"tmsEnabled": false,
"commProxyEnabled": true,
"services": [
"Premier",
"VMR_Pool_Static",
"VMR"
],
"logo": "/provisioning/image/2472"
},
"latitude": 45.786368,
"longitude": -78.505822,
"active": false,
"summary": null
},
"summary": {
"totalDevices": 2
},
"vip": false
}
我在网站json4swift.com上使用了这个json(完整列表,上面已经缩短了)来构建我的dto对象并将它们放在我的项目中
再次缩短长度,如果请求我可以添加更多(更新它以包括所有,因为它是问题的一部分):
Room.swift
struct Room : Codable {
let id : String?
let name : String?
let shortName : String?
let displayName : String?
let inService : Bool?
let managed : Bool?
let capacity : Int?
let schedulingOption : String?
let location : Location?
let summary : RoomSummary?
let vip : Bool?
enum CodingKeys: String, CodingKey {
case id = "id"
case name = "name"
case shortName = "shortName"
case displayName = "displayName"
case inService = "inService"
case managed = "managed"
case capacity = "capacity"
case schedulingOption = "schedulingOption"
case location
case summary
case vip = "vip"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decodeIfPresent(String.self, forKey: .id)
name = try values.decodeIfPresent(String.self, forKey: .name)
shortName = try values.decodeIfPresent(String.self, forKey: .shortName)
displayName = try values.decodeIfPresent(String.self, forKey: .displayName)
inService = try values.decodeIfPresent(Bool.self, forKey: .inService)
managed = try values.decodeIfPresent(Bool.self, forKey: .managed)
capacity = try values.decodeIfPresent(Int.self, forKey: .capacity)
schedulingOption = try values.decodeIfPresent(String.self, forKey: .schedulingOption)
location = try Location(from: decoder)
summary = try RoomSummary(from: decoder)
vip = try values.decodeIfPresent(Bool.self, forKey: .vip)
}
}
Location.swift
struct Location : Codable {
let id : String?
let name : String?
let shortName : String?
let displayName : String?
let city : String?
let country : String?
let account : Account?
let latitude : Double?
let longitude : Double?
let active : Bool?
let summary : LocationSummary?
enum CodingKeys: String, CodingKey {
case id = "id"
case name = "name"
case shortName = "shortName"
case displayName = "displayName"
case city = "city"
case country = "country"
case account
case latitude = "latitude"
case longitude = "longitude"
case active = "active"
case summary
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decodeIfPresent(String.self, forKey: .id)
name = try values.decodeIfPresent(String.self, forKey: .name)
shortName = try values.decodeIfPresent(String.self, forKey: .shortName)
displayName = try values.decodeIfPresent(String.self, forKey: .displayName)
city = try values.decodeIfPresent(String.self, forKey: .city)
country = try values.decodeIfPresent(String.self, forKey: .country)
account = try Account(from: decoder)
latitude = try values.decodeIfPresent(Double.self, forKey: .latitude)
longitude = try values.decodeIfPresent(Double.self, forKey: .longitude)
active = try values.decodeIfPresent(Bool.self, forKey: .active)
summary = try LocationSummary(from: decoder)
}
}
Account.swift
struct Account : Codable {
let id : String?
let name : String!
let shortName : String!
let displayName : String!
let active : Bool!
let exchangeEnabled : Bool!
let tmsEnabled : Bool!
let commProxyEnabled : Bool!
let services : [String]!
enum CodingKeys: String, CodingKey {
case id = "id"
case name = "name"
case shortName = "shortName"
case displayName = "displayName"
case active = "active"
case exchangeEnabled = "exchangeEnabled"
case tmsEnabled = "tmsEnabled"
case commProxyEnabled = "commProxyEnabled"
case services = "services"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decodeIfPresent(String.self, forKey: .id)
name = try values.decodeIfPresent(String.self, forKey: .name)
shortName = try values.decodeIfPresent(String.self, forKey: .shortName)
displayName = try values.decodeIfPresent(String.self, forKey: .displayName)
active = try values.decodeIfPresent(Bool.self, forKey: .active)
exchangeEnabled = try values.decodeIfPresent(Bool.self, forKey: .exchangeEnabled)
tmsEnabled = try values.decodeIfPresent(Bool.self, forKey: .tmsEnabled)
commProxyEnabled = try values.decodeIfPresent(Bool.self, forKey: .commProxyEnabled)
services = try values.decodeIfPresent([String].self, forKey: .services)
}
}
我的问题是Room.Location
& Room.Location.Account
与Room
重复,请参见下方的截图
为什么要像我那样反序列化我的对象?
答案 0 :(得分:1)
我已经检查了你的代码,稍作修改,否则代码不起作用:我使用相同的json,但更正了summary
属性类型:
struct Room : Codable {
let id : String?
let name : String?
let shortName : String?
let displayName : String?
let inService : Bool?
let managed : Bool?
let capacity : Int?
let schedulingOption : String?
let location : Location?
let summary : Dictionary<String, Int>?
let vip : Bool?
}
struct Location : Codable {
let id : String?
let name : String?
let shortName : String?
let displayName : String?
let city : String?
let country : String?
let account : Account?
let latitude : Double?
let longitude : Double?
let active : Bool?
let summary : String?
}
struct Account : Codable {
let id : String?
let name : String!
let shortName : String!
let displayName : String!
let active : Bool!
let exchangeEnabled : Bool!
let tmsEnabled : Bool!
let commProxyEnabled : Bool!
let services : [String]!
}
do {
let jsonDecoder = JSONDecoder()
let object = try jsonDecoder.decode(Room.self, from: data) // Here is Room.self, not [Room].self, due to json root object is dictionary
print("object: ", object)
} catch {
print("error: ", error)
}
运作良好并打印:
对象:房间(id:可选(“506e9a1d-cded-4853-a9df-7f8a57d6550d”), name:可选(“TeleTwo”),shortName:可选(“2”),displayName: 可选(“2”),inService:可选(true),托管:可选(true), capacity:可选(2),schedulingOption:可选(“VC Scheduling”), location:可选(sss.Location(id: 可选(“50b07258-2668-416e-aef4-a8a48e9e7389”),姓名: 可选(“远程呈现测试”),shortName:可选(“远程呈现” 测试“),displayName:可选(”远程呈现测试“),城市: 可选(“Nash”),国家/地区:可选(“美国”),帐户: 可选(sss.Account(ID: 可选(“509788c6-197f-40f1-a7f7-274a23af9062”),名称: Swift.ImplicitlyUnwrappedOptional.some( “发展”), 简称: Swift.ImplicitlyUnwrappedOptional.some( “开发”), 显示名称: Swift.ImplicitlyUnwrappedOptional.some(“Dev”),活跃: Swift.ImplicitlyUnwrappedOptional.some(真), exchangeEnabled: Swift.ImplicitlyUnwrappedOptional.some(false),tmsEnabled: Swift.ImplicitlyUnwrappedOptional.some(假), commProxyEnabled: Swift.ImplicitlyUnwrappedOptional.some(true),服务: Swift.ImplicitlyUnwrappedOptional&GT;。一些([ “超级”, “VMR_Pool_Static”,“VMR”]))),纬度:可选(45.786368000000003), 经度:可选(-78.505821999999995),有效:可选(false), 摘要:nil)),summary:可选([“totalDevices”:2]),vip: 可选(假))
似乎一切正常。