Day#21 Chat

前言

昨天引用了许多函式库,今天就来使用他们所提供的功能,真正来实作chatroom内容吧~~

Spinner

RegisterViewController

spinner.show(in: view)

首先我们在画面加上spinner的元件。

接着在之前的程序中,加上更多判断spinner的逻辑。
当该使用者存在时,就把spinner dismiss掉。

DatabaseManager.shared.userExists(with: email, completion: { [weak self] exists in
    guard let strongSelf = self else { // prevent from memory leak
        return
    }

    DispatchQueue.main.async {
        strongSelf.spinner.dismiss()
    }

    guard !exists else {
        strongSelf.alertUserLoginError(message: "user for that email address already exists")
        return
    }

    FirebaseAuth.Auth.auth().createUser(withEmail: email, password: password, completion: { authResult, error in

        guard authResult != nil, error == nil else {
            print("error creating user")
            return
        }

        // data entry
        DatabaseManager.shared.insertUser(with: ChatAppUser(firstName: firstname,
                                                            lastName: lastname,
                                                            emailAddress: email))
        // todo: flow check
        strongSelf.navigationController?.dismiss(animated: true, completion: nil)
    })
})

table view

ConversationViewController

我们将table view的边线,在subview load进来时显示。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    tableView.frame = view.bounds
}

聊天

终於进到聊天的view controller了!

ChatViewController

首先,先引入函式库。其中MessageKit是一个处理跟聊天相关所有行为的函式库。

import UIKit
import MessageKit

资料结构

struct Message: MessageType {
    var sender: SenderType
    var messageId: String
    var sentDate: Date
    var kind: MessageKind
}

struct Sender: SenderType {
    var photoURL: String // URL
    var senderId: String
    var displayName: String
}

main view controller

class ChatViewController: MessagesViewController {

    // collection of messages
    private var messages = [Message]()
    
    private let selfSender = Sender(photoURL: "",
                                    senderId: "1",
                                    displayName: "Joe Smith")
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        messages.append(Message(sender: selfSender,
                                messageId: "1",
                                sentDate: Date(),
                                kind: .text("Hello world message hello world message hello world message")))
        
        messagesCollectionView.messagesDataSource = self
        messagesCollectionView.messagesLayoutDelegate = self
        messagesCollectionView.messagesDisplayDelegate = self
    }
    

}

Extension

每次都会需要新增,因为我们在上面有将messagesDataSource, messagesLayoutDelegate, messagesDisplayDelegate指派给自己。
因此需要新增以下几个方法:

  1. 目前的sender回传为自己。
  2. 每个item定义为messageKit中的section
  3. 每个section的数量
extension ChatViewController: MessagesDataSource, MessagesLayoutDelegate, MessagesDisplayDelegate {
    func currentSender() -> SenderType {
        return selfSender
    }
    
    func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType {
        // MessageKit use section to separate every single message
        return messages[indexPath.section] // a single section, per message
    }
    
    func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int {
        return messages.count
    }
    
    
}

结语

赫然发现测试时每次都要把app从模拟器中卸载再重装,完全是因为忘记把logout的功能加上去XDD
那明天就来实作这边吧!

若上述内容有误或可以改进的部分,欢迎留言以及提出任何指教~
谢谢 (´・∀・`)


<<:  Day 21 来开始介绍Cypress

>>:  Android Studio初学笔记-Day21-AlertDialog(2)

【Day 12】卑鄙源之 Hook (下) - 侦测 Hook

环境 Windows 10 21H1 Visual Studio 2019 前情提要 在【Day 1...

DAY 12- 公钥密码学(非对称式加密)

"想传讯息给我吗?想要的话就去传吧!我把公钥都放在那里了。" --- 我们先前讲...

如果我是主力,我会怎样割韭菜

所谓的主力,就是有绝对多的资金,或是大量持有某一档股票,最大的优势就是容易操控股票价格。 今年一堆散...

Day 23 XIB跳转页面以及UIAlertController的练习(1/3)

今天我们来练习,XIB的跳页功能跟Alert提示框吧~ 首先拉一个Button,按下後提示框跳出,按...

Day 30 | ContentProvider

可以使用ContentProvider将资料库分享给其他应用程序共享资讯,或从其他应用程序操作资料 ...