본문 바로가기
iOS/RxSwift

[RxSwift] Hello, RxSwift !

by 0inn 2022. 10. 11.

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