У меня есть json объект, содержащий вложенные словари, которые я пытаюсь разобрать в swift:
{
"ambientLightColor" : [100.0, 200.0, 300.0],
"lights" : {
"light1" : {"position" : [ 5, 5, 0], "direction" : [0,0,0], "color" : [0.0,0.7,0.3]},
"light2" : {"position" : [-5, 5, 0], "direction" : [0,0,0], "color" : [0.8,0.2,0.1]},
"light3" : {"position" : [ 0,-5, 0], "direction" : [0,0,0], "color" : [0.3,0.3,0.9]}
}
}
Поскольку объект root - это словарь с ключами в виде строк, я приведу его к такому для начала, как это сделано в примере здесь https://developer.apple.com/swift/blog/?id=37
if let scene = sceneJSON as? [String: Any] {
if let ambientRGB = scene["ambientLightColor"] as? [f1] {
ambientLightColor = f3(ambientRGB[0],ambientRGB[1],ambientRGB[2])
}
if let lights = scene["lights"] as? [String: Any] {
for (lightName, properties) in lights {
let position = properties["position"]
let direction = properties["direction"]
let color = properties["color"]
self.lights.append(Light(position: f3(position[0], position[1], position[2]), direction: f3(direction[0], direction[1], direction[2]), color: f3(color[0], color[1], color[2])))
}
}
}
Поскольку значения словаря root сначала приводятся как «Любые», они должны затем быть преобразованы в более Используемый тип при использовании записи. Это достаточно просто для первой записи, где я использую if let ... as? [f1] для приведения значения словаря [100.0, 200.0, 300.0] к массиву одиночных чисел с плавающей точкой перед их использованием для создания float3 (я не уверен, как напрямую приводить к float3 из массива чисел с плавающей запятой, но это не важно ).
Второй случай немного сложнее, поскольку он снова содержит другой вложенный словарь, хотя я не хочу использовать if для каждого отдельного элемента, скорее я хотел бы использовать a для l oop как показано выше. Теперь я знаю, что должен также преобразовать значение словаря свойств из любого типа в словарь в форме [String: [f1]].
Я попытался преобразовать его в первое преобразование словаря:
if let lights = scene["lights"] as? [String: [String: [f1]] {
for (lightName, properties) in lights {
let position = properties["position"]
let direction = properties["direction"]
let color = properties["color"]
self.lights.append(Light(position: f3(position[0], position[1], position[2]), direction: f3(direction[0], direction[1], direction[2]), color: f3(color[0], color[1], color[2])))
}
Это дает мне ошибку из-за того, что [f1] является необязательным, и при запуске он также не находит json объектов, соответствующих этому типу.
Я также пытался
if let lights = scene["lights"] as? [String: [String: Any] {
for (lightName, properties) in lights {
let position = properties["position"] as! [f1]
let direction = properties["direction"] as! [f1]
let color = properties["color"] as! [f1]
self.lights.append(Light(position: f3(position[0], position[1], position[2]), direction: f3(direction[0], direction[1], direction[2]), color: f3(color[0], color[1], color[2])))
}
Хотя это дает мне любую ошибку из-за того, что я не могу соединить NSNumber с плавающей точкой, что очень трудно исправить, когда они находятся в массиве.
Я также пытался
if let lights = scene["lights"] as? [String: Any] {
for case let (lightName, properties as? [String:[f1]]) in lights {
let position = properties["position"]
let direction = properties["direction"]
let color = properties["color"]
self.lights.append(Light(position: f3(position[0], position[1], position[2]), direction: f3(direction[0], direction[1], direction[2]), color: f3(color[0], color[1], color[2])))
}
Кажется, что это был бы хороший способ написать решение, но swift не примет приведение типов в скобках из пары словарей.
Очень хотелось бы получить хороший краткий способ сделать это. Спасибо.