[swift] Swift PromiseKit를 이용한 앱 내 실시간 채팅 구현 방법

소개

실시간 채팅은 많은 앱에서 중요한 기능입니다. 이번 글에서는 Swift와 PromiseKit를 사용하여 앱 내에 실시간 채팅을 구현하는 방법을 알아보겠습니다.

PromiseKit 소개

PromiseKit은 Swift에서 비동기 작업을 처리하는 라이브러리로, 콜백 헬(callback hell)을 피할 수 있도록 해줍니다. PromiseKit은 약속(promise)이 완료되면 결과를 반환하거나 오류를 처리하는 간편한 인터페이스를 제공합니다.

Firebase를 이용한 실시간 데이터베이스 설정

실시간 채팅을 구현하기 위해 여러 서비스를 사용할 수 있지만, 이번 예제에서는 Firebase를 사용하여 실시간 데이터베이스를 구성합니다.

  1. Firebase 콘솔에 접속하여 프로젝트를 생성합니다.
  2. 생성한 프로젝트의 “실시간 데이터베이스” 탭으로 이동합니다.
  3. “실시간 데이터베이스 생성”을 클릭하여 데이터베이스를 생성합니다.

Firebase SDK 설치 및 프로젝트 설정

  1. Firebase SDK를 가져오기 위해 Podfile에 다음을 추가합니다:
     pod 'Firebase/Database'
    
  2. 터미널에서 pod install 명령을 실행하여 Firebase SDK를 설치합니다.
  3. 프로젝트의 .xcworkspace 파일을 열어 Firebase SDK를 사용하도록 설정합니다.

PromiseKit를 사용하여 Firebase 데이터베이스에 접근하기

  1. Firebase 실시간 데이터베이스에 접근하기 위해 DatabaseReference를 사용합니다:
     import Firebase
     import PromiseKit
    
     class ChatManager {
         private var ref: DatabaseReference!
    
         init() {
             ref = Database.database().reference()
         }
    
         func sendMessage(message: String) -> Promise<Void> {
             return Promise { seal in
                 let childRef = ref.child("messages").childByAutoId()
                 let messageData = ["message": message]
    
                 childRef.setValue(messageData) { error, _ in
                     if let error = error {
                         seal.reject(error)
                     } else {
                         seal.fulfill(())
                     }
                 }
             }
         }
     }
    
  2. 위의 예제 코드에서는 sendMessage 메소드를 사용하여 메시지를 Firebase 데이터베이스에 보냅니다. 이 때, Promise<Void>를 반환하도록 선언하며, 해당 프로미스는 전송이 성공적으로 완료되면 이행(fulfill)됩니다.

실시간 채팅 화면 구성

실시간 채팅 화면을 구성하기 위해 UITableView를 사용하고, Firebase의 observe 메소드를 사용하여 채팅 메시지 업데이트를 감지합니다.

import UIKit
import PromiseKit
import Firebase

class ChatViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var messageTextField: UITextField!

    private var messages = [String]()
    private var ref: DatabaseReference!
    private var chatManager: ChatManager!

    override func viewDidLoad() {
        super.viewDidLoad()

        ref = Database.database().reference()
        chatManager = ChatManager()

        observeMessages()
    }

    func observeMessages() {
        ref.child("messages").observe(.childAdded) { [weak self] snapshot in
            guard let messageData = snapshot.value as? [String: String], let message = messageData["message"] else {
                return
            }

            self?.messages.append(message)
            self?.tableView.reloadData()
        }
    }

    @IBAction func sendMessageButtonTapped(_ sender: UIButton) {
        guard let message = messageTextField.text else { return }

        chatManager.sendMessage(message: message).done {
            // 전송 성공 처리
            self.messageTextField.text = ""
        }.catch { error in
            // 전송 실패 처리
            print(error.localizedDescription)
        }
    }
}

extension ChatViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return messages.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ChatCell", for: indexPath)
        cell.textLabel?.text = messages[indexPath.row]
        return cell
    }
}

결론

이번 글에서는 Swift PromiseKit와 Firebase를 사용하여 앱 내에 실시간 채팅을 구현하는 방법을 살펴보았습니다. PromiseKit를 사용하면 콜백 헬을 피하고 비동기 작업을 간편하게 처리할 수 있습니다. Firebase는 강력한 실시간 데이터베이스 기능을 제공하여 실시간 채팅 앱을 쉽게 구현할 수 있게 해줍니다.

참고 자료