- "Swift 4 Decodable JSON" try JSONDecoder().decode([Room].self, from: jsonData).
, , , , JSONDecoder JSON Room(from: Decoder) . , , JSON.
Decodable, JSON, Room, .
, Xcode:
import UIKit
struct Room {
let name: String
var devices: [Device]
fileprivate struct DeviceInRoom: Decodable {
let name: String
let room: String
}
static func rooms(from data: Data) -> [Room]? {
return (try? JSONDecoder().decode([DeviceInRoom].self, from: data))?.rooms()
}
}
struct Device {
let name: String
}
fileprivate extension Array where Element == Room.DeviceInRoom {
func rooms() -> [Room] {
var rooms = [Room]()
self.forEach { deviceInRoom in
if let index = rooms.index(where: { $0.name == deviceInRoom.room }) {
rooms[index].devices.append(Device(name: deviceInRoom.name))
} else {
rooms.append(Room(name: deviceInRoom.room, devices: [Device(name: deviceInRoom.name)]))
}
}
return rooms
}
}
let json = """
[
{
"name": "TV",
"room": "Living Room"
},
{
"name": "LightBulb 1",
"room": "Living Room"
}
]
"""
if let data = json.data(using: .utf8),
let rooms = Room.rooms(from: data) {
print(rooms)
}
- , :
import UIKit
struct Room {
let name: String
var devices: [Device]
}
struct Device {
let name: String
}
struct RoomContainer: Decodable {
let rooms: [Room]
private enum CodingKeys: String, CodingKey {
case name
case room
}
init(from decoder: Decoder) throws {
var rooms = [Room]()
var objects = try decoder.unkeyedContainer()
while objects.isAtEnd == false {
let container = try objects.nestedContainer(keyedBy: CodingKeys.self)
let deviceName = try container.decode(String.self, forKey: .name)
let roomName = try container.decode(String.self, forKey: .room)
if let index = rooms.index(where: { $0.name == roomName }) {
rooms[index].devices.append(Device(name: deviceName))
} else {
rooms.append(Room(name: roomName, devices: [Device(name: deviceName)]))
}
}
self.rooms = rooms
}
}
let json = """
[
{
"name": "TV",
"room": "Living Room"
},
{
"name": "LightBulb 1",
"room": "Living Room"
}
]
"""
if let data = json.data(using: .utf8),
let rooms = (try? JSONDecoder().decode(RoomContainer.self, from: data))?.rooms {
print(rooms)
}
. try? . , - JSONDecoder , , !:)