Combine 공부하면서 Todo App 구현

준우·2024년 1월 16일
0

Swift 이야기

목록 보기
3/19
post-thumbnail

Combine 이란?

  • Apple 에서 만든 새로 만든 비동기 이벤트처리 프레임워크
  • RxSwift 의 Made by Apple 이라고 생각하면 편해요
  • 그리고 iOS 13부터 사용할 수 있어요

주요 구성 요소로는

Publisher : 이벤트를 발행하는 친구에요. Output, Failure 타입으로 구현되어 있어요.

Subscriber : 이벤트를 받는 친구에요. Input, Failure 타입으로 구현되어 있어요.

Operator : Publisher 가 내보내는 값을 처리하는 친구에요. Input, Output 로 구성되어 있어요.

실제로 구현해보기

1. 먼저 Model을 만들어 봅시다.

import Foundation

struct ToDo {
    var uuid = UUID()
    var title: String
}

2. 그 다음, ViewModel 을 만들어 봅시다.

  • 여기서 todoListPublisher 는 VC로 이벤트를 발행하는 역할을 합니다.
  • PassthroughSubject 와 CurrentValueSubject 가 있어요.
  • PassthroughSubject는 초기값을 가지고 있지 않아요. 하지만, CurrentValueSubject는 초기값을 가지고 있어야 해요.
  • 데이터의 흐름은 "todoList" 에 값이 먼저 들어가고, todoList를 todoListPublisher 에 todoList 데이터를 실어서 VC로 이벤트를 발행할 거에요.
class ViewModel {
    var todoListPublisher = CurrentValueSubject<[ToDo], Never>([])
    var todoList = [ToDo]()
}

3. VC에서는 ViewModel의 todoListPublisher 이벤트를 받을 준비를 해봅시다.

  • bind() 라는 메서드를 임의로 만들었어요.
  • viewModel의 todoListPublisher 를 구독할 준비를 해요.
  • receive 는 이벤트가 발행되는 위치를 변경해줘요.
  • sink 는 이벤트를 구독한 후 처리를 해줘요.
  • viewModel 의 todoList 에 viewModel 이 발행한 데이터를 대입해줘요. 그리고 테이블을 갱신해주면 이벤트를 받아 처리하는 것은 끝났어요.
  • store(in:) 메서드는 구독 객체(AnyCancellable)를 Set에 추가해서 구독한 이벤트들을 관리해줘요.
  • 여기서, sink는 AnyCancellable을 반환합니다.
func bind() {
        viewModel.todoListPublisher
            .receive(on: RunLoop.main) // 메인에서 이벤트를 발행한다는 뜻이에요.
            .sink { [weak self] todoList in
                self?.viewModel.todoList = todoList
                self?.tableView.reloadData()
            }.store(in: &subscriptions)
    }

4. 이제 VC에서 이벤트를 보내봅시다.

// VC 에서 ViewModel의 todoList에 데이터를 추가하는 곳
createVC.actionHandler = { [weak self] todo in
            self?.viewModel.addTodoList(todo: todo)
            print("#### \(self?.viewModel.todoList)")
        }
        
// ViewModel 의 addTodoList 메서드
func addTodoList(todo: ToDo) {
    todoList.append(todo) // 1. 들어온 todo 데이터를 todoList에 추가
    todoListPublisher.send(todoList) // 2. 추가된 todoList를 todoListPublisher 에 이벤트를 전달
}

// 3. 전달된 데이터는 위 VC에서 데이터를 받기로 한 곳으로 이동

0개의 댓글