RxSwift: Reactive Programming with Swift 책 읽고 꼼꼼히 정리해보려고 합니다 . . !
한글로 잘 정리된 github도 참고하며 정리합니다 . .
RxSwift란 ?
RxSwift는 관찰 가능한 시퀀스와 기능적 스타일 연산자를 사용하여 비동기식 및 이벤트 기반 코드를 구성하기 위한 라이브러리로 스케줄러를 통해 매개변수화된 실행을 허용합니다 .
뭔소리지 . . ?
즉, RxSwift는 새로운 데이터에 반응하고 순차적이며 격리된 방식으로 처리할수 있도록하는 비동기식 프로그램입니다.
비동기 API
Apple은 항상 iOS SDK에서 비동기 코드를 작성하는데 도움이 되는 수많은 API를 제공합니다.
- NotificationCenter
- Delegate Pattern
- Grand Central Dispatch (GCD)
- Closure
- Combine
비동기 프로그래밍 용어
1. State, and specifically, shared mutable state
앱의 State(상태)를 관리하는 것(특히 여러가지 비동기 구성요소를 공유할 때)은 RxSwift를 통해 배울 수 있는 중요한 포인트 중 하나입니다.
2. 명령형 프로그래밍
명령형 프로그래밍이란 선언형 프로그래밍과 반대되는 개념으로 프로그래밍의 상태와 상태를 변경시키는 구문의 관점에서 연산을 설명하는 프로그래밍 패러다임의 일종입니다.
- 앱에게 정확히 '언제', '무엇을' 하라고 말하고 싶을 때 명령형 코드를 쓸 수 있다.
- 인간이 복잡하고 비동기적인 앱을 만들기 위해 명령형 코드를 사용하는 것은 너무 어렵다.
- iOS ViewController의 viewDidAppear(_:)를 예시로 확인해보자.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
setupUI()
connectUIControls()
createDataSource()
listenForChanges()
}
문제점
: 각각의 method가 순서대로 잘 실행될지 보증할 수 없으며 누군가 실수로 method의 순서를 바꿨다면 이로 인해 앱이 다르게 작동될 수 있습니다.
3. 부(수) 작용들
부수작용이란 현재 scope 외 상태에서 일어나는 모든 변화를 뜻합니다.
각각의 코드에 대해 해당 코드가 어떤 부수작용을 발생시킬 수 있는 코드인지, 단순 과정을 나열한 것인지, 명확한 결과값만을 발생시키는 것인지 정확히 인지하고 있는 것이 중요합니다.
4. 선언형 코드
- 명령형 프로그래밍에서의 상태 변화는 자유자재로 가능하다.
- 함수형 코드에서는 부수작용을 일으킬 수 없다.
- RxSwift는 이 두 가지를 아주 잘 결합하여 동작하게 한다.
명령형 프로그래밍 + 함수형 프로그래밍
자유로운 상태변화 + 추적 / 예측 가능한 결과값
- 선언형 코드를 통해 동작을 정의할 수 있으며 RxSwift는 관련 이벤트가 있을 때마다 이러한 동작을 실행하고 작업할 수 있는 불변의 고유한 데이터 입력을 제공한다.
5. Reactive systems
- 반응 : 항상 UI를 최신 상태로 유지하며 가장 최근의 앱 상태를 표시
- 복원력 : 각각의 행동들은 독립적으로 정의되며 에러 복구를 위해 유연하게 제공됨
- 탄력성 : 코드는 다양한 작업 부하를 처리하며 종종 lazy full 기반 데이터 수집, 이벤트 제한 및 리소스 공유 같은 기능을 구현
- 메세지 전달 : 구성요소는 메시지 기반 통신을 사용하여 재사용 및 고유한 기능을 개선하고, 라이프 사이클과 클래스 구현을 분리
RxSwift 기초
1. Observables
- Observable<T> 클래스는 Rx 코드의 기반
- T 형태의 데이터 snapshot을 전달할 수 있는 일련의 이벤트를 비동기적으로 생성하는 기능
- 하나 이상의 observers(관찰자)가 실시간으로 어떤 이벤트에 반응하고 앱 UI를 업데이트하거나 생성하는지 처리하고 활용 가능
- Observable은 다음 세 가지 유형의 이벤트만 방출 가능
- next 이벤트 : 데이터 값을 전달하는 이벤트로 종료 이벤트가 방출될 때까지 무한한 양 방출 가능
- completed 이벤트 : 이벤트 시퀀스를 성공적으로 종료하는 이벤트로 추가 이벤트를 내보내지 않음
- error 이벤트 : error Observable과 함께 종료되며 추가 이벤트를 내보내지 않음
시간이 지남에 따라 발생하는 비동기 이벤트에 대해 이야기해보자.
- 상기 세 가지 유형의 Observable 이벤트는 Observable 또는 Observer의 본질에 대한 어떠한 가정도 하지 않는다.
- 델리게이트 프로토콜이나 클래스 통신을 위한 클로저를 삽입할 필요가 없다.
Finite observable sequences
ex. iOS 앱에서 인터넷을 통해 파일을 다운로드하는 코드
API.download(file: "http://www...")
.subscribe(onNext: { data in
... append data to temporary file
},
onError: { error in
... display error to user
},
onCompleted: {
... use downloaded file
})
- API.download(file:)은 네트워크를 통해 들어오는 Data 값을 방출하는 Observable<Data> 인스턴스를 리턴할 것이다.
- onNext 클로저를 통해 next 이벤트를 받을 수 있고, 예제에서 받은 데이터를 temporary file에 저장할 것이다.
- onError 클로저를 통해 error 이벤트를 받을 수 있고, alert 메시지 같은 action을 취할 수 있다.
- 최종적으로 onCompleted 클로저를 통해 completed 이벤트를 받을 수 있으며 이를 통해 새로운 viewController를 push하여 다운로드 받은 파일을 표시하는 등의 액션을 취할 수 있다.
Infinite observable sequences
ex. 기기의 가로 / 세로 모드에 따라 반응해야하는 코드
UIDevice.rx.orientation
.subscribe(onNext: { current in
switch current {
case .landscape:
... re-arrange UI for landscape
case .portrait:
... re-arrange UI for portrait
}
})
- UIDevice.rx.orientation은 Observable<Orientation>을 통해 만든 가상의 코드
- Orientation을 받을 수 있고, 받은 값을 앱의 UI에 업데이트할 수 있다.
- 해당 Observable에서는 절대 발생하지 않을 이벤트이기 때문에 onError나 onCompleted 파라미터는 건너뛸 수 있다.
2. Operators
UIDevice.rx.orientation
.filter { value in
return value != .landscape
}
.map { _ in
return "Portrait is the best!"
}
.subscribe(onNext: { string in
showAlert(text: string)
})
UIDevice.rx.orientation이 .landscape 또는 .portrait 값을 생성할 때마다 Rx는 각각의 연산자를 데이터의 형태로 방출
- filter는 .landscape 이 아닌 값만 내놓는다.
- 만약 .portrait 값이 들어온다면 map 연산자는 해당 방향값을 택할 것이며 "Portrait is the best!"로 변환할 것이다.
- subscribe를 통해 결과로 next 이벤트를 구현한다. String 값을 전달하며 해당 텍스트로 alert를 화면에 표시하는 method를 호출한다.
3. Schedulers
- Scheduler는 Rx에서 dispatch queue와 동일한 것으로 훨씬 강력하고 쓰기 쉽다.
- 기존까지 GCD를 통해 일련의 코드를 작성했다면 스케쥴러를 통한 RxSwift는 다음과 같이 돌아간다.
- network subscription은 (1)로 표시된 Custom NSOperation Scheduler에서 구동된다.
- 여기서 출력된 데이터는 다음 블록인 Background Concurrent Scheduler의 (2)로 가게 된다.
- 최종적으로, 네트워크 코드의 마지막 (3)은 Main Thread Serial Scheduler로 가서 UI를 새로운 데이터로 업데이트 하게 된다.
App Architecture [MVVM]
RxCocoa
RxCocoa는 RxSwift의 동반 라이브러리로 UIKit과 Cocoa 프레임워크 기반 개발을 지원하는 모든 클래스를 보유하고 있습니다.
ex. RxCocoa를 이용해 UISwitch의 상태를 확인하기
toggleSwitch.rx.isOn
.subscribe(onNext: { enabled in
print( enabled ? "It's ON" : "it's OFF")
})
RxCocoa는 UITextField, URLSession, UIViewController 등에 rx를 추가하여 사용합니다.
'iOS > RxSwift' 카테고리의 다른 글
[RxSwift] Combining Operators (0) | 2022.11.18 |
---|---|
[RxSwift] Transforming Operators (0) | 2022.11.17 |
[RxSwift] Filtering Operators (0) | 2022.10.12 |
[RxSwift] Subjects (0) | 2022.10.12 |
[RxSwift] Observable (0) | 2022.10.11 |