У меня была эта проблема раньше, вот что я сделал, чтобы исправить ее. Допустим, так выглядит моя база данных. Обратите внимание на соглашение об именах, в данном примере это случай змеи.
Допустим, я хочу создать массив пользователей из этого снимка и заполнить мой tableView. Это сложно, потому что snapshot.value на самом деле не JSON и имеет значение Any. Вероятно, именно поэтому ваше приложение падает или в вашем случае тип не соответствует.
Давайте создадим модель для наших пользователей. Это будет выглядеть примерно так:
class User: Codable {
var firstName: String
var lastName: String
var ageNumber: Int
enum CodingKeys: String, CodingKey {
case firstName,lastName
case ageNumber = "age"
}
}
Итак, позвольте мне указать кое-что по-настоящему быстро. В моей базе данных firebase пользовательские свойства выглядят как «first_name», «age» «last_name». В моей пользовательской модели это выглядит как «firstName», «ageNumber» «lastName». Поэтому мне пришлось добавить ключи кодирования из-за возраста, а не из-за имени или фамилии. Имя и фамилия меняются сами по себе, когда я устанавливаю keyCodingStrategy на моем декодере.
Вот так выглядит этот код. Оставьте несколько комментариев, чтобы лучше объяснить, что делает код.
var items = [Item]()
override func viewDidLoad() {
super.viewDidLoad()
// Use your database reference here.
let ref = Database.database().reference(withPath: "users")
ref.observe(.value) { (snapshot) in
//First create a dict out of the snapshot value
guard let dict = snapshot.value as? [String: Any] else { return }
//Create a decoder this is why I don't need to chage the first_name to firstName
//inside my coding keys
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
//The key is the UID and the value is what we need to create a new users
dict.forEach { (key, value) in
do {
//Create new user and add it to our users array
//We convert the value to data for the decoder with this line of code
let testListData = try JSONSerialization.data(withJSONObject: value, options: .prettyPrinted)
let testList = try decoder.decode(TestList.self, from: testListData)
testList.items.forEach({ (item) in
self.items.append(item)
})
}
catch let err {
print(err.localizedDescription)
}
}
//Reload Table View
}
}
Надеюсь, это поможет.
Отредактировано
Таким образом, основываясь на предоставленных вами JSON. Вам придется создать свои структуры примерно так.
struct TestList: Codable {
var items: [Item]
}
struct Item: Codable {
var itemType: String
var one: String
var two: String
var three: String
var four: String
enum CodingKeys: String, CodingKey {
case itemType
case one = "1"
case two = "2"
case three = "3"
case four = "4"
}
}
Надеюсь, это решит вашу проблему.