Чат беседа для FireBase в Swift - PullRequest
0 голосов
/ 03 июня 2018

Я использовал эту модель:

import Foundation
class Chat {
var message: String?
var senderID: String
var receiverID: String
var timestamp : String

init(messageTextString: String?, senderIDNumber: String, receiverIDNumber: String, timeStampString: String){
    message = messageTextString
    senderID = senderIDNumber
    receiverID = receiverIDNumber
    timestamp = timeStampString
}
}

А для ChatViewController:

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
    return chats.count
}

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ChatCollectionViewCell    
     let senderIDNumber = Auth.auth().currentUser?.uid
        if chats[indexPath.row].senderID == senderIDNumber {
        if let chatsText = chats[indexPath.row].message{
            let size = CGSize(width: 250, height: 1000)
            let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
            let estimatedFrame = NSString(string: chatsText).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 18)], context: nil)
            cell.messageSend.frame = CGRect(x:8,y:0,width:estimatedFrame.width + 16, height:estimatedFrame.height + 20)
            cell.textBubbleView.frame = CGRect(x:0,y:0,width:estimatedFrame.width + 16 + 8, height:estimatedFrame.height + 20)
         //showOutgoingMessage(text: chats[indexPath.row].message)
    }
            cell.messageSend.text = chats[indexPath.row].message
    }
    else {
          /*cell.messageReceived.text = chats[indexPath.row].message */
            let chatsText = chats[indexPath.row].message
            let size = CGSize(width: 250, height: 1000)
            let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
            let estimatedFrame = NSString(string: chatsText!).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 18)], context: nil)
            cell.messageSend.frame = CGRect(x:view.frame.width - estimatedFrame.width,y:0,width:estimatedFrame.width + 16, height:estimatedFrame.height + 20)
            cell.textBubbleView.frame = CGRect(x:view.frame.width - estimatedFrame.width,y:0,width:estimatedFrame.width + 16 + 8, height:estimatedFrame.height + 20)
    }
    return cell
 }

@objc func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
if let chatsText = chats[indexPath.row].message {
    let size = CGSize(width: 250, height: 1000)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        let estimatedFrame = NSString(string: chatsText).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 18)], context: nil)
        return CGSize(width: view.frame.width, height: estimatedFrame.height + 20)
    }
    return CGSize(width: view.frame.width, height: 200)
}

func loadPosts() {
    let ref = Database.database().reference()
    let senderIDNumber = Auth.auth().currentUser?.uid
    ref.child("chats").queryOrdered(byChild: "senderID").queryEqual(toValue: senderIDNumber).observe(.childAdded) { (snapshot: DataSnapshot) in
        if  let dict = snapshot.value as? [String: Any] {
            let messageText = dict["message"] as! String
            let senderIDNumber = dict["senderID"] as! String
            let receiverIDNumber = dict["receiverID"] as? String
            let timestamp = dict["timestamp"] as? String
            let chat = Chat(messageTextString: messageText, senderIDNumber: senderIDNumber, receiverIDNumber: receiverIDNumber!, timeStampString: timestamp!)
            //append(post) to array
            self.chats.append(chat)
            print(self.chats)
           self.collectionView.reloadData()
        }
    }
}

 func loadPostsReceivedMessage() {
    let ref = Database.database().reference()
    ref.child("chats").queryOrdered(byChild: "receiverID").queryEqual(toValue: receiverIDNumber).observe(.childAdded) { (snapshot: DataSnapshot) in
        if  let dict = snapshot.value as? [String: Any] {
            let messageText = dict["message"] as! String
            let senderIDNumber = dict["senderID"] as! String
            let receiverIDNumber = dict["receiverID"] as? String
            let timestamp = dict["timestamp"] as? String
            let chat = Chat(messageTextString: messageText, senderIDNumber: senderIDNumber, receiverIDNumber: receiverIDNumber!, timeStampString: timestamp!)
            self.chats.append(chat)
            print(self.chats)
            self.collectionView.reloadData()
        }
    }
}

}

Я хочу иметь возможность различать исходящие и входящие сообщения, но не смог этого сделать.Я подумал о создании логического inComing для различения исходящего и входящего сообщения;но не знал, как реализовать.Мне понадобятся помощь и совет, большое спасибо

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Возможность отличить отправленное сообщение от полученного сообщения так же просто, как добавить свойство к объекту чата, поэтому вы можете получить что-то вроде этого:

class Chat {
    var message: String
    var senderID: String
    var receiverID: String
    var timestamp : String
    var isFromCurrentUser: Bool = false // You'll only need to change this property if the message is from the current sender.

    init(messageTextString: String?, senderIDNumber: String, receiverIDNumber: String, timeStampString: String){
        self.message = messageTextString
        self.senderID = senderIDNumber
        self.receiverID = receiverIDNumber
        self.timestamp = timeStampString
    }
}

Послеизменяя свой объект, вы захотите взглянуть на то, как вы извлекаете данные.Я бы порекомендовал переименовать loadPosts() в listenForChatItemAdded() и изменить функцию на следующее:

примечание: использование запросов для этого не обязательно.Запросы особенно полезны, когда вам нужен только определенный набор данных;здесь вам лучше будет захватить данные и отсортировать их после инициализации объектов.

func loadPosts() {
    let ref = Database.database().reference()
    let senderIDNumber = Auth.auth().currentUser?.uid
    ref.child("chats").observe(.childAdded) { (snapshot: DataSnapshot) in
        if  let dict = snapshot.value as? [String: Any] {
            let messageText = dict["message"] as! String
            let senderIDNumber = dict["senderID"] as! String
            let receiverIDNumber = dict["receiverID"] as? String
            let timestamp = dict["timestamp"] as? String

            let chat = Chat(messageTextString: messageText, senderIDNumber: senderIDNumber, receiverIDNumber: receiverIDNumber!, timeStampString: timestamp!)

            let currentUserUID = Auth().auth().currentUser!.uid
            if senderID == currentUserUID {
                chat.isFromCurrentUser = true
            }

            //append(post) to array
            self.chats.append(chat)

            //after adding the new chat tot the array, sort the array
            let sorted = filtered.sorted { (chat1, chat2) -> Bool in
                return chat1.timestamp > chat2.timestamp
            }

            // update the current array with the sorted array
            self.chats = sorted

            // reload the collectionView
            self.collectionView.reloadData()
        }
    }
}

Наконец, просто проверьте созданное нами свойство, чтобы определить, как настроить визуально ячейку.Я хотел бы создать два подкласса UICollectionViewCell.Один для отправителя и один для получателя.Если чат был отправлен текущим пользователем, создайте ячейку с подклассом отправителя, если чат был отправлен кем-либо еще, используйте подкласс получателя.

Надеюсь, это поможет, ура!

0 голосов
/ 03 июня 2018

Firebase не может выполнить запрос !!! (В частности, мультисортировка) .. Нужно перейти на firestorm (Новая бета-версия хранилища Firebase) или использовать угловой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...