[swift] RxSwift를 사용한 채팅 기능 구현 방법

채팅 기능을 구현하는 동안 비동기적인 데이터 흐름을 관리하기 위해 RxSwift와 RxCocoa를 사용할 수 있습니다. RxSwift는 Observable 시퀀스로부터 이벤트를 방출하고 이를 처리하는 함수형 프로그래밍 패턴을 제공합니다. 채팅 앱에서 사용되는 예제를 통해 RxSwift를 사용한 채팅 기능 구현 방법을 살펴보겠습니다.

1. RxSwift 및 RxCocoa 설치

RxSwift를 사용하기 위해 프로젝트에 RxSwift 및 RxCocoa를 추가해야 합니다. CocoaPods를 사용하는 경우, Podfile에 다음과 같이 추가합니다:

pod 'RxSwift', '~> 5'
pod 'RxCocoa', '~> 5'

설치를 위해 터미널에서 pod install을 실행합니다.

2. 채팅 메시지 모델 작성

struct ChatMessage {
    let content: String
    let sender: String
    let timestamp: Date
}

위의 예제와 같이 채팅 메시지를 나타내는 ChatMessage 모델을 작성합니다. 이 모델은 메시지 내용(content), 보낸 사람(sender), 타임스탬프(timestamp)로 구성됩니다.

3. 채팅 화면 구성

class ChatViewController: UIViewController {
    
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var messageTextField: UITextField!
    @IBOutlet weak var sendButton: UIButton!
    
    let disposeBag = DisposeBag()
    
    var chatMessages = BehaviorRelay<[ChatMessage]>(value: [])
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupTableView()
        setupSendButton()
        
        observeChatMessages()
    }
    
    func setupTableView() {
        // 테이블 뷰 설정
    }
    
    func setupSendButton() {
        sendButton.rx.tap
            .subscribe(onNext: { [weak self] in
                self?.sendMessage()
            })
            .disposed(by: disposeBag)
    }
    
    func observeChatMessages() {
        chatMessages
            .bind(to: tableView.rx.items) { tableView, row, element in
                let cell = tableView.dequeueReusableCell(withIdentifier: "ChatCell", for: IndexPath(row: row, section: 0))
                cell.textLabel?.text = element.content
                cell.detailTextLabel?.text = "\(element.sender) - \(element.timestamp)"
                return cell
            }
            .disposed(by: disposeBag)
    }
    
    func sendMessage() {
        guard let message = messageTextField.text, !message.isEmpty else {
            return
        }
        
        let newMessage = ChatMessage(content: message, sender: "Me", timestamp: Date())
        var messages = chatMessages.value
        messages.append(newMessage)
        chatMessages.accept(messages)
        
        messageTextField.text = ""
    }
}

위의 예제 코드에서는 채팅 화면을 구성하는 ChatViewController 클래스를 작성하였습니다. chatMessages라는 BehaviorRelay를 사용하여 채팅 메시지를 관리합니다. sendButton을 터치하면 sendMessage() 메소드가 호출되어 chatMessages에 새로운 메시지를 추가하고, tableView에 메시지를 표시합니다.

4. 채팅 화면과 View Model 연결

class ChatViewModel {
    
    let chatMessages = BehaviorRelay<[ChatMessage]>(value: [])
    
    func sendMessage(_ message: String) {
        let newMessage = ChatMessage(content: message, sender: "Me", timestamp: Date())
        var messages = chatMessages.value
        messages.append(newMessage)
        chatMessages.accept(messages)
    }
    
}
class ChatViewController: UIViewController {
    
    let viewModel = ChatViewModel()
    let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        observeChatMessages()
    }
    
    func observeChatMessages() {
        viewModel.chatMessages
            .bind(to: tableView.rx.items) { tableView, row, element in
                let cell = tableView.dequeueReusableCell(withIdentifier: "ChatCell", for: IndexPath(row: row, section: 0))
                cell.textLabel?.text = element.content
                cell.detailTextLabel?.text = "\(element.sender) - \(element.timestamp)"
                return cell
            }
            .disposed(by: disposeBag)
    }
    
    func sendMessage() {
        guard let message = messageTextField.text, !message.isEmpty else {
            return
        }
        
        viewModel.sendMessage(message)
        
        messageTextField.text = ""
    }
}

이렇게 View Model을 도입하여 채팅 화면과 데이터를 분리할 수 있습니다. ChatViewModel 클래스에 sendMessage() 메소드를 추가하여 채팅 메시지를 처리하고 chatMessages에 추가하는 로직을 이관합니다. ChatViewController에서는 view Model의 chatMessages를 구독하여 화면에 표시하는 로직을 작성합니다.

5. 결론

이제 RxSwift와 RxCocoa를 사용하여 채팅 기능을 구현하는 방법을 알아보았습니다. RxSwift를 사용하면 비동기적인 데이터의 처리를 효과적으로 관리할 수 있으며, View Model을 통해 UI와 로직을 분리할 수 있습니다. 채팅 앱 외에도 다양한 애플리케이션에서 RxSwift를 활용할 수 있으니, 관심 있는 분들은 더 많은 자료를 참고하시기 바랍니다.