| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
- 동시(Concurrent)
- popupView
- Dispatch Queue
- NSCache
- MapKit
- WeatherAPP
- swift
- MVVM
- Rxcocoa
- Swift Package Manager
- 의존성 관리 도구
- NewsApp
- cocoapods
- SPM
- 라이선스 저작권
- 비동기(Async)
- ios
- OpenSource
- Control Event
- 동기(Sync)
- pagination
- Multiple Cell Type
- Traits
- Segmented Control
- flatMap
- 직렬(Serial)
- Transforming Operators
- IAMPopup
- RxSwift
- Library
- Today
- Total
IAM iOS
[RxSwift] TODO List App Using Filter Operations 본문
What we will be Building?
우선순위와 함께 작성한 메모를 Segmented Control를 활용하여 TableView에 띄우기

AddTaskViewController
메모를 작성하는 View에서 선택한 우선순위와 메모를 메인 View로 넘기기 위해
(프로토콜이나 델리게이트 패턴을 사용하지 않고) RxSwift를 사용하여 task를 전달 !
1. enum 타입, 우선순위(Priority)와 전달할 데이터(Task)를 담은 구조체
enum Priority: Int {
case high
case medium
case low
}
struct Task {
let title: String
let priority: Priority
}
2. (Subscribe가 가능한) Task를 반환할 Subject를 생성한다.
private let taskSubject = PublishSubject<Task>()
var taskSubjectObservable: Observable<Task> {
return taskSubject.asObserver()
}
3. 우선순위를 체크하고, 메모를 작성한 뒤 저장 버튼을 누르면 task를 담은 Subject 전송한다.
@IBAction func save() {
guard let priority = Priority(rawValue: self.prioritySegmentedControl.selectedSegmentIndex),
let title = self.taskTitleTextField.text else { return }
let task = Task(title: title, priority: priority)
// Subject 호출, 전송
taskSubject.onNext(task)
self.dismiss(animated: true)
}
참고
- 메모를 저장할 때 Segmented Control은 High, Medium, Low만 있고, 메인 View는 All을 포함하고 있으므로 선택한 세그먼트 Index에 -1을 해준다.
let priority = Priority(rawValue: self.prioritySegmentedControl.selectedSegmentIndex - 1)
TaskListViewController
1. Observable (taskSubjectObservable)을 구독하여 task를 가져온다.
- addTaskVC에서 전달받은 Task를 담을 BehaviorRelay<[tasks]>
- BehaviorRelay<[tasks]>에 [task] 배열을 담기 위해 새로운 배열(existingTasks)을 만든다.
참고
- RxSwift인 Subject와는 다르게 Relay는 RxCocoa의 클래스
BehaviorRelay는 BehaviorSubject의 Wrapper 클래스
value를 통해서 현재의 값을 가져올 수 있으며, Variable이 Deprecate 되면서 대신에 BehaviorRelay를 사용하면 된다.
- ~Subject와 ~Relay의 차이점
~Subject는 .completed, .error의 이벤트가 발생하면 subscribe가 종료되는 반면,
~Relay는 .completed, .error를 발생하지 않고, Dispose 되기 전까지 계속 작동하기 때문에 UI Event에서 사용하기 적절하다.
import RxCocoa
private var tasks = BehaviorRelay<[Task]>(value: [])
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let navC = segue.destination as? UINavigationController,
let addTVC = navC.viewControllers.first as? AddTaskViewController else { fatalError("Controller not found..")}
// subscribe
addTVC.taskSubjectObservable
.subscribe(onNext: { [unowned self] task in
let priority = Priority(rawValue: self.prioritySegmentedControl.selectedSegmentIndex - 1)
var existingTasks = self.tasks.value // [Task]
existingTasks.append(task)
self.tasks.accept(existingTasks)
self.filterTasks(by: priority) // Filtering
}).disposed(by: disposeBag)
}
2. 우선순위에 따라 작업 Filtering
- priority == nil (All) → 전체 Task 배열 담기
- priority == High / Medium / Low → map을 통해 Filter 작업에 액세스
- Priority? 옵셔널 처리하는 이유 → Priority에서 All case는 존재하지 않음
private var filteredTasks = [Task]()
...
private func filterTasks(by priority: Priority?) {
if priority == nil { // All
self.filteredTasks = self.tasks.value
self.updateTableView()
} else { // High, Medium, Low
// 매핑 후 필터 처리
self.tasks.map { tasks in
return tasks.filter { $0.priority == priority! }
}.subscribe(onNext: { [weak self] tasks in
self?.filteredTasks = tasks
self?.updateTableView()
}).disposed(by: disposeBag)
}
}
3. 해당 Segmented Control을 선택 → 선택한 priority에 해당하는 tasks 배열을 TableView에 띄운다.
@IBAction func priorityValueChanged(segmentControl: UISegmentedControl) {
let priority = Priority(rawValue: segmentControl.selectedSegmentIndex - 1)
filterTasks(by: priority)
}
- filteredTasks 배열에 담긴 수만큼 반환
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.filteredTasks.count
}
GitHub - camosss/RxSwift: RxSwift 공부한 내용 정리
RxSwift 공부한 내용 정리. Contribute to camosss/RxSwift development by creating an account on GitHub.
github.com
'RxSwift' 카테고리의 다른 글
| [RxSwift] MVVM-C with Building Memo App (1) MVVM-C(Clean Architecture), Model, 메모리 저장소(Memory Storage) (0) | 2022.05.12 |
|---|---|
| [RxSwift] MVVM with RxSwift (0) | 2022.04.09 |
| [RxSwift] Building Weather App Using RxCocoa (0) | 2022.04.09 |
| [RxSwift] Building News App Using Transforming Operators (0) | 2022.04.03 |
| [RxSwift] Implementing Photo Filter App Using RxSwift (0) | 2022.03.29 |