У меня есть 2 проблемы с отображением данных в таблице из Firebase.
Печать работает. Я получаю доступ к Firebase, но в TableView ничего не добавляется. Пожалуйста, посмотрите на мой код и исправьте, где я ошибаюсь.
это моя модель
class Exercises {
var titleExercise = ""
var descriptionExercise = ""
init (titleExercise: String, descriptionExercise: String) {
self.titleExercise = titleExercise
self.descriptionExercise = descriptionExercise
}
}
Это мой ViewController
class ExercisesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//MARK: Properties
var refWorkout: String = ""
var workout: TrainingProgram?
var ref: DatabaseReference!
@IBOutlet weak var tableView: UITableView!
var exercises = [Exercises]()
//MARK: Methods
override func viewDidLoad() {
super.viewDidLoad()
fetchExercises()
tableView.dataSource = self
tableView.delegate = self
refWorkout = workout!.title
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return exercises.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ExercisesTableViewCell
let workouts = exercises[indexPath.item]
cell.titleLabel.text = workouts.titleExercise
cell.descriptionLabel.text = workouts.descriptionExercise
return cell
}
func fetchExercises() {
Database.database().reference().child("programs").child("OPEN SPACE").child("exercises").observe(.childAdded) { (snapshot) in
print(snapshot.value)
if let dict = snapshot.value as? [String: AnyObject] {
let newTitle = dict["title"] as! String
let newDescription = dict["description"] as! String
let exerciseTableCell = Exercises(titleExercise: newTitle, descriptionExercise: newDescription)
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
А у меня второй вопрос. Он также решает эту проблему.
Как видите, у меня есть refWorkout = workout!.title Вот заголовок из предыдущего ViewController, а refWorkout — дочерний для Firebase. Если я напишу следующий код
ref = Database.database().reference().child("programs").child(refWorkout).child("exercises")
ref.observe(.childAdded) { (snapshot) in
print(snapshot.value)
}
Все будет работать. Печать будет работать. Но если я вставлю этот код в func fetchExercises() -> это будет выглядеть так
func fetchExercises() {
Database.database().reference().child("programs").child(refWorkout).child("exercises").observe(.childAdded)...
Мое приложение вышло из строя. Помогите пожалуйста с двумя вопросами. Спасибо!





Это распространенная ошибка, вы слишком рано перезагружаете табличное представление и не назначаете/добавляете результат в массив источника данных.
observe API работает асинхронно, поместите строку для перезагрузки табличного представления в замыкание
func fetchExercises() {
Database.database().reference().child("programs").child("OPEN SPACE").child("exercises").observe(.childAdded) { (snapshot) in
print(snapshot.value)
if let dict = snapshot.value as? [String: Any] { // most likely all values are value type
let newTitle = dict["title"] as! String
let newDescription = dict["description"] as! String
let exercise = Exercises(titleExercise: newTitle, descriptionExercise: newDescription)
self.exercises.append(exercise)
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
Примечание:
Ваш класс содержит 3 плохие практики:
И в большинстве случаев достаточно структуры и даже констант. я бы порекомендовал
struct Exercise {
let title : String
let description : String
}
В структуре вы получаете инициализатор бесплатно.
Тогда snapshot.value может быть массивом. Пожалуйста, добавьте результат print(snapshot.value) к вопросу.
Я понял. Спасибо ;) И, пожалуйста, объясните мне, почему мой второй вопрос не работает. В моем первом ViewController у меня есть collectionView с заголовками. Когда пользователь нажимает на одну из ячеек, пользователь переходит к следующему ViewController (с TableView). В моем табличном представлении я должен отображать данные из Firebase, но я должен знать ссылку, которую я должен выбрать.
Итак, я решил сохранить ссылку как var. var refWorkout — это мой заголовок из предыдущего ViewController. Итак, я хочу сделать следующее: func fetchExercises() { Database.database().reference().child("programs").child(refWorkout).child("exercises").... Но у меня вылетает, когда я хочу поставить child(refWorkout)
Потому что вы вызываете fetchExercises перед присвоением значения refWorkout. Переместить линию fetchExercises()позадиrefWorkout = workout!.title
Спасибо. Все работает. Хорошего дня ! :))
Не помогло :(