Лучший способ обработки извлечения данных из Firebase в ячейке TableView - PullRequest
0 голосов
/ 21 января 2020

В своем чате я показываю текущему пользователю его чаты с другими пользователями в виде таблицы. Каждая ячейка в табличном представлении - это информация, аватар и имя противоположного пользователя. Эти данные легко хранить в объекте чата, но проблема в том, что противоположный пользователь мог изменить свой аватар или имя в этот момент.

Следовательно, я выбираю аватар и имя противоположного пользователя в Конфигурация ячейки чата. Он работает нормально, но я не уверен, что есть лучший способ, так как я не продам сетевой вызов Firebase в каждой ячейке.

Вот мой метод настройки ячейки:

    func configureCell(from chat: Chat){
    // 1st Get opposite user id
    if let currentUser = Auth.auth().currentUser{
        let user1 = chat.people.first
        let user2 = chat.people.last
        let user1Id = user1?["id"] ?? ""
        let user2Id = user2?["id"] ?? ""
        var oppositeUserId = ""
        if user1Id == currentUser.uid{
            oppositeUserId = user2Id
        }else{
            oppositeUserId = user1Id
        }
        //2nd Fetch opposite user doc
        let oppositeUserDocRef = References.Instance.getUserDocRef(for: oppositeUserId)
        oppositeUserDocRef.getDocument { (oppositeUserDocSnapshot, error) in
            if error != nil{
                print("ERROR FETCHING OPPOSITE USER DOC:: ERROR IS:  \(error?.localizedDescription ?? "")")
                return
            }
            // 3rd get opposite user avatar url and name
            if let otherUserDic = oppositeUserDocSnapshot?.data(){
                if let avatarDic = otherUserDic["avatar"] as? [String: String]{
                    let avatarUrl = avatarDic["url"] ?? ""
                    self.avatarView.sd_setImage(with: URL(string: avatarUrl),
                                          placeholderImage: nil, options: .refreshCached)
                }
                if let name = otherUserDic["name"] as? String{
                    self.uiLabelChatTitle.text = name
                }
            }
        }
    }
}

Ответы [ 2 ]

1 голос
/ 21 января 2020

Я никогда не использовал Firebase, но для чего-то подобного я бы сказал, заполнил массив объектов 'chatDetails' в одном сетевом запросе, а затем настроил каждую повторно используемую ячейку

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let chat = self.chatDetails[indexPath.row]

        let cell = tableView.dequeueReusableCell(withIdentifier: "identifier") as! ChatDetailsCell

        cell.configureCell(chat: chat)

        return cell

    }
0 голосов
/ 23 января 2020

Как они предложили в комментариях, предварительная выборка данных была бы лучшим решением. Это сложно и зависит от деталей каждого приложения. Моей целью было mimi c Функциональность чата в WhatsApp, обновляющая информацию о пользователях в реальном времени.

Вот что я сделал для достижения этой цели:

    func showChats(){
    guard let currentUser = Auth.auth().currentUser else{
        return
    }
    let profileController = UserProfileController.instance
    if let snapshot = profileController.chats{
        for document in snapshot.documents{
            let chat = ChatController.instance.getChat(from: document)
            chats.append(chat)
            print("GOT CHAT:::: \(document.data())")
        }
        tableview.reloadData()
    }
    else{
        print("NOTHING IN INBOX!!!!")
    }
    // Attach listeners to chat users docs to listen for change in avatars and names
    // 1st: Loop through each chat to get people and know opposite user id
    for (i, var chat) in chats.enumerated(){
        let person1 = chat.people.first
        let person2 = chat.people.last
        let person1Id = person1?["id"] ?? ""
        let person2Id = person2?["id"] ?? ""
        var oppositeUserId = ""
        var opposteUsrIsPerson1 = false
        if person1Id == currentUser.uid{
            oppositeUserId = person2Id
            opposteUsrIsPerson1 = false
        }
        else{
            oppositeUserId = person1Id
            opposteUsrIsPerson1 = true
        }
        // 2nd: Fetch opposite user doc and add listener to it
        let oppositeUserDocRef = References.Instance.getUserDocRef(for: oppositeUserId)
        let docListener = oppositeUserDocRef.addSnapshotListener { (oppositeUserDocSnapshot, error) in
            if error != nil {
                print("ERROR FETCHING OTHER PERSON DOC:: ERROR IS:  \(error?.localizedDescription ?? "")")
                return
            }
            // 3rd: get other user avatar url and name from his doc
            if let oppositeUserDic = oppositeUserDocSnapshot?.data(){
                var avatarUrl = ""
                var name = ""
                if let avatarDic = oppositeUserDic["avatar"] as? [String: String]{
                    avatarUrl = avatarDic["url"] ?? ""
                }
                if let oppositeUsrName = oppositeUserDic["name"] as? String{
                    name = oppositeUsrName
                }
                // 4th: Create ChatPerson object with the fetched values and replace the existing one
                let chatPerson = ChatPerson(id: oppositeUserId, name: name, avatarUrl: avatarUrl)
                if opposteUsrIsPerson1{
                    chat.people[0] = chatPerson.toDictionalry()
                }
                else{
                    chat.people[1] = chatPerson.toDictionalry()
                }
                // 5th: Update data and reload the chat row
                self.chats[i] = chat
                let indexpath = IndexPath(row: i, section: 0)
                self.tableview.reloadRows(at: [indexpath], with: .automatic)
            }
        }
        //6th: Add doc listener to liteners list to remove it later in deinit()
        chatUserListeners.append(docListener)
    }
}

В функции deinit контроллера view () l oop через слушателей, чтобы удалить их:

    deinit {
    for listener in chatUserListeners{
        listener.remove()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...