Обновите этот объект с новой информацией в массиве и для отображения таблицы Swift - PullRequest
1 голос
/ 30 октября 2019

Я использую базу данных Firebase в реальном времени и внедряю данные профиля пользователя с usersFriend и местоположением. Мне нужно реализовать обновление в массиве объектов и показать обновленные значения в виде таблицы. Я пытался, но мне не удалось обновить объект, а затем перезагрузить просмотр таблицы. Функция уже разработана.

Мне нужно показать обновленный массив объектов с новыми значениями и отобразить в виде таблицы.

var myFriendsDataSource = [FriendClass]()

func watchForChangesInMyFriends() { 
  let usersRef = self.ref.child("profiles") usersRef.observe(.childChanged, with: { snapshot in 
    let key = snapshot.key 
    if let friendIndex = self.myFriendsDataSource.firstIndex(where: { $0.uid == key} ) { 
      let friend = self.myFriendsDataSource[friendIndex] 
      print("found user \(friend.batteryStatus), updating")
      self.myFriendsDataSource[friendIndex] = friend 
      self.tableView.reloadData() 
    } 
  }) 
}

Класс:

class FriendClass {

    var uid = ""
    var name = ""
    var batteryStatus = Int()
    var latitude = Double()
    var longitude = Double()
    var timeStamp = Int64()

    //var profilePic

    init(withSnapshot: DataSnapshot) {

        self.uid = withSnapshot.key
        self.name = withSnapshot.childSnapshot(forPath: "name").value as? String ?? "No Name"
        self.batteryStatus = withSnapshot.childSnapshot(forPath: "batteryStatus").value as? Int ?? 0
        self.latitude = withSnapshot.childSnapshot(forPath: "latitude").value as? Double ?? 0.0
        self.longitude = withSnapshot.childSnapshot(forPath: "longitude").value as? Double ?? 0.0
        self.timeStamp = withSnapshot.childSnapshot(forPath: "timeStamp").value as? Int64  ?? 0

    }
}

Обновлено:

func loadUsersFriends() {

let uid = "zzV6DQSXUyUkPHgENDbZ9EjXVBj2"
let myFriendsRef = self.ref.child("userFriends").child(uid)
myFriendsRef.observeSingleEvent(of: .value, with: { snapshot in
let uidArray = snapshot.children.allObjects as! [DataSnapshot]
   for friendsUid in uidArray {
          self.loadFriend(withUid: friendsUid.key)
          print(friendsUid)
         }
     })
 }

func loadFriend(withUid: String) {
  let thisUserRef = self.ref.child("profiles").child(withUid)
  thisUserRef.observeSingleEvent(of: .value, with: { snapshot in
  let aFriend = FriendClass(withSnapshot: snapshot)
  self.myFriendsDataSource.append(aFriend)
  print(self.myFriendsDataSource)
  self.tableView.reloadData()
  self.watchForChangesInMyFriends()

        })
    }

Обновление 2:

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 70
    }
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 10
    }
}

extension ViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myFriendsDataSource.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FriendListTableViewCell", for: indexPath) as! FriendListTableViewCell
        let dic = myFriendsDataSource[indexPath.row]

        cell.frndName.text = dic.name

        return cell
    }

1 Ответ

3 голосов
/ 30 октября 2019

Учитывая обсуждение вышеупомянутого комментария, я думаю, что вам нужно обновить ваш watchForChangesInMyFriends метод, как показано ниже, чтобы фактически обновить источник данных новыми данными о друзьях. Вам также следует выполнить все обновления пользовательского интерфейса в основном потоке, и поскольку нет гарантии, что это закрытие будет выполняться в основном потоке, вам необходимо принудительно обновить обновление tableView в основном потоке.

func watchForChangesInMyFriends() { 
  let usersRef = self.ref.child("profiles") usersRef.observe(.childChanged, with: { snapshot in 
    let key = snapshot.key 
    if let friendIndex = self.myFriendsDataSource.firstIndex(where: { $0.uid == key} ) { 
      let friend = self.myFriendsDataSource[friendIndex] 
      print("found user \(friend.batteryStatus), updating")
      self.myFriendsDataSource[friendIndex] = FriendClass(withSnaphot: snapshot)
      DispatchQueue.main.async {
        self.tableView.reloadData()
      } 
    } 
  }) 
}

Этотакже рекомендуется обновлять только измененные данные tableView, а не перезагружать весь tableView. Вероятно, вы можете использовать индекс массива для генерации IndexPath для соответствующей строки, а затем просто перезагрузить эту строку. Не видя ваши методы tableView, я не могу быть точным, но, вероятно, это будет выглядеть примерно так:

let indexPath = IndexPath(row: friendIndex, section: 0)
DispatchQueue.main.async {
  self.tableView.reloadRows(at: [indexPath], with: .automatic)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...