한 줄 소감 : 알엑스 .. 잭 앤 휴와 함께라면 뿌실 수 있다.
RxSwift란?
ReactiveX를 도입한 Swift 전용 구현 라이브러리이다.
(이게 뭔데? 사실 .. 개념 자체보다 어떻게 구현되는지, 어떻게 동작되는지가 더 중요하다. 일단 넘어가자.)
RxSwift의 키워드
알엑스에서 주의해야 하는 키워드는 세가지이다.
- Observer
- 이벤트를 방출 -> 전달받는 패턴이다.
- 일종의 Notification처럼 동작한다. (알림을 보내고 .. 알림을 받는 식의 ..)
- Observable을 이용해서 이벤트를 보내면
- Observer을 통해 이벤트를 전달 받는다.
- Iterator
- map, filter, reduce 등과 같은 메서드를 생각해보자.
- 이런 함수들의 주의할 점은 순서이다.
- filter를 하고 reduce를 하는 것과 reduce를 하고 filter를 하는 것에 결과값의 차이가 있다.
- 이런 식의 데이터의 흐름이 존재하는데
- RxSwift 역시 Iterator을 통해 데이터의 흐름을 관리하고 순차적으로 메서드를 실행할 수 있다.
- map, filter, reduce 등과 같은 메서드를 생각해보자.
- Functional Programming
Observable - Observer
간단하게 말하면,
- Observable : 이벤트 방출, 전달
- Observer : 이벤트에 대한 처리
예를 들어서 아래 두가지 상황이 있다고 가정하자.
ex) 로그인을 하는 상황
- 사용자가 텍스트에 이름 입력하게 된다. (→ Obversable)
- 각 문자 입력
- → 상황에 대한 전달
- → ~ 입력 한다?(이벤트 보내는 중)
- 입력값에 따른 결과를 처리한다. (→ Observer)
- 입력에 따른 버튼 활성화, 경고 문구의 색상 변화 등
- → 입력값에 따른 결과 반환(이벤트 받아서 상황에 맞는 결과 반환)
ex) 유튜브 (구독)
- 유튜브에는 여러 채널이 존재한다.
- 각 채널 주들이 각자의 채널에 영상을 업로드 하는 것 = 이벤트를 계속 보내는 것을 의미한다. (전세계의 채널 주인들은 영상 올리는 것에 대한 이벤트를 보낸다.)
- 이 중 하나의 채널을 구독한 경우, 아무리 여러 채널에서 이벤트를 보내도 구독한 채널에 대한 이벤트만 받을 수 있다. → 이벤트를 받을 객체는 따로 존재한다.
이 두가지 상황에 대해서 알 수 있는 것은 아래와 같다.
✅ 이벤트를 보내는 객체와 이벤트를 받는 객체로 나뉘어져 있다는 것
✅ Observable이 많아도 Observer가 없다면 보내는 이벤트에 대한 처리를 할 수 없다.
RxSwift Basic
Observable은 영상을 업로드하고 (유튜브를 생각해보면)
= 이벤트를 전달하고
= 계속 이벤트를 전달하고
Observer은 영상을 받아본다.
= 전달 받은 이벤트를 처리한다. (화면 전환, 알림창 등의)
= 계속 이벤트를 관찰하고 있어야 한다.
*1:1 대응으로 보이지만, Notification처럼 여러개가 등록될 수 있다.
(일 대 다, 다 대 일, 다 대 다 등 ..)
🤔 만약 Observable에 Observer가 없다면?
해당 옵저버블에서 이벤트를 보내도 이를 전달 받아 처리할 객체가 없기 때문에 Observable을 만든다면 Observer를 만들어야 한다.
🤔 만약 나중에 Observer가 생긴다면?
Observer가 생긴 시점 이후로 이벤트를 처리할 수 있다.
이벤트의 종류
Observable이 이벤트를 방출하고, Observer가 이벤트를 처리하는 코드라고 했을 때
여기서 말하는 이벤트는 크게 두가지 종류로 나눌 수 있다.
- 유한하게 방출할 수 있는 이벤트
- 무한하게 방출할 수 있는 이벤트
무한한 이벤트
예를 들어 가로모드와 같은 이벤트를 생각해보자.
- 세로 모드에서 가로모드로 바뀌게 된다면?
- 이러한 이벤트는 한번도 발생하지 않을 수도 있지만, 여러번 (셀 수 없을 만큼) 발생할 수 있다.
- 이러한 이벤트의 횟수를 제한할 수 없다. (= 이벤트에 대한 한계를 지을 수 없다.)
- 주로 UI와 관련된 이벤트의 경우는 무한한 이벤트라고 할 수 있다.
- 데이터의 흐름이 끝나지 않고 무한하게 발생한다.
- Infinite Observable Sequences
유한한 이벤트
그렇다면 어떤 경우에 유한하다고 할 수 있을까?
- 넷플릭스에서 오프라인으로 저장한 경우
- 백업/복구를 한 경우
- 만약 위의 두가지 경우가 용량이 엄청 큰 경우라면?
- 한번에 이벤트를 처리하는 것이 어려울 것이다.
- 그래서 조금씩, 점진적으로 이벤트를 처리하게 된다.
위의 이미지를 통해서 볼 수 있는 것처럼 점진적으로 이벤트가 처리되는 것을 볼 수 있다.
(NASA API에서 이미지를 다운로드 받게 되는 경우를 볼 수 있다.)
🚨 다운로드 버튼 누르는 것은 무한하다. (이는 사용자에게 인터렉션을 받는 작업이므로 UI와 관련된 작업이라고 할 수 있다.)
🚨 다운로드를 받는 하나의 과정에 대해서 유한하다고 할 수 있다.
이런 경우를 유한한 시퀀스라고 한다.
🤔 map, filter, reduce와 같은 고차함수를 사용한 옵저버블도 유한 시퀀스라고 볼 수 있다.
이벤트의 상황/상태
용량이 큰 이미지를 다운로드 받을 때 과정은 아래와 같다.
- 점진적으로 다운로드를 실행한다.
- 네트워크 연결이 유실되거나
- 다운로드 실패하거나
- 상태 코드 등의 오류로 다운로드가 되지 않는다면
- error의 형태로 반환된다/
- 성공적으로 다운로드가 완료되면, 이미지가 보일 것이다.
이벤트를 보내고 받는다. 로 끝나는 것이 아니라 하나의 이벤트 과정 안에 여러 상태가 존재하게 된다.
위와 같은 경우를 Rx에서는 아래와 같이 대응하고 있다.
(= 만약, 다양한 상황이 존재하는 이벤트일 경우 Rx에서는 어떻게 대응할까?)
- Next (= Append Buffer = Emit)
- 점진적으로 다운로드를 한다.
- 다운로드 한 뒤 최신의 데이터를 전달한다. (이벤트를 받을 객체에게)
- 여러번 발생 할 수 있다.
- Completed (= ImageView에 Image로 보여진다 = Notification)
- 다운로드가 완료된 경우를 의미한다.
- 한번 완료되면 끝.
- 이후로 계속 지속적으로 발생하지 않는다.
- Error (= Alert = Notification)
- 다운로드가 실패된 경우로
- 디코딩을 실패한 경우일 수도 있고
- 상태코드가 오류난 경우일 수도 있고
- 네트워크 연결이 유실될 경우일 수도 있다.
- 위의 Completed와 마찬가지로 한번 완료되면 끝이다.
- 이후로 계속 지속적으로 발생하지 않는다.
- 다운로드가 실패된 경우로
Next/Completed/Error
=> 하나의 이벤트가 전달-처리되는 과정에서 어떤 상황인지에 따라 3가지 경우로 나눠서 처리할 수 있다.
큰 용량의 이미지라면 하나의 다운로드에 대해서 3-4번 정도의 Next가 발생하고,
1번의 Completed 또는 Error가 발생한다.
이러한 하나의 흐름, 일련의 흐름을 Observable에 대한 Life Cycle이라고 한다.
🤔 왜 Life Cycle이라고 하는가
- Completed가 되었다면 그 이후로는 이벤트 전달이 되지 않는다. (에러도 마찬가지)
- 완료와 에러는 시퀀스 중에서 가장 마지막에 실행
- 완료와 에러는 둘 중에 하나만 호출
- Notification이 발생한 이후에는 이벤트는 끝나게 된다.
여기서 UI가 무한한 이벤트인지 알 수 있다.
- UI에 대한 처리에는 Completed, Error가 없다.
- 그러므로, 끝이 없기 때문에 유한하지 않고 무한한 이벤트라는 것을 알 수 있다.
흐름
Observable -- 이벤트를 전달 --> Observer -- 이벤트를 전달 받아 상황에 따른 처리 --> Next/Completed/Error
- 여기서 Observable과 Observer를 연결하는 것을 Subscribe라고 한다.
- 그리고 이벤트가 요청될 때 요청의 종류에 따라서 operator가 달라진다.
- 동일하게 버튼을 누르는 이벤트에 대해서
- 다양한 처리를 할 수 있다.
- just
- take(5)
- combineLatest ..
- 이런 식의 다양한 처리를 할 수 있는 요소를 Rx에서 Operator라고 한다.
앞서 말했던 것과 같이, 이벤트를 여러번 방출해도 이를 전달 받을 객체가 없다면 이벤트에 대한 처리를 할 수 없다.
즉, Observable이 있어도 Observer가 subscribe하지 않으면 이벤트 처리를 할 수 없다.
Dispose
dispose는 무한한 시퀀스에 대해서 유한하게 제한을 걸고 싶을 때 사용하는 것이다.
(🔥 이 부분은 제대로 이해가 되지 않아서 이후에 다시 살펴볼 것 !!! 🔥)
Bind
- subscribe(구독)에 대한 확장판이다.
- UI를 다룰 때 나오는데, UI 요소의 경우 completed, error의 경우가 없기 때문에 이런 상황일 때의 코드를 관리할 필요가 없다.
- (굳이 구독,취소를 할 필요가 없기 때문에 bind로 관리)
RxCocoa
- UI적인 요소를 관리하는 Rx
- RxSwift를 기반으로 만들어졌다.
중요한 내용 정리를 해보자.
Observable LifeCycle
- Observable을 생성한다. (이벤트를 방출할 준비를 한다.) 보통, 구현되어 있는 Operator를 사용한다.
- Subscribe가 되면 Observable이 실행된다.
- next를 통해 이벤트(제스쳐, 인스턴스 등)을 emit한다.
- Life Cycle 도중에 오류가 발생한다면, error 이벤트를 / 정상적으로 이벤트가 완료된다면 completed를 notification 한다.
- deinit되는 시점, 즉 sequence가 종료되는 시점에 dispose된다.
- Life Cycle에서 error 또는 completed를 전달 받으면, 시퀀스가 종료되고 종료된 이후에는 더 이상 이벤트가 발생하지 않는다. (= Observable은 재사용이 불가하다.)
Disposable
- Disposable은 구독 중인 stream을 원하는 시기에 종료/처리 할 수 있도록 도와준다.
- Observable은 모두 Disposable을 반환한다.
- 이를 통해서 stream을 종료하고
- 실행되던 시퀀스를 모두 종료한다.
- 하지만 next 이벤트가 무수하게 emit될 수 있는 상황에서는 dispose가 되지 않는다.
'Swift > RxSwift' 카테고리의 다른 글
[🔥Rx뿌셔] Subscribe (0) | 2022.10.25 |
---|---|
[🔥Rx뿌셔] Observable (2) | 2022.10.24 |
[🔥Rx뿌셔] Intro (1) | 2022.10.24 |
[🌱SeSAC] Creating and Subscribing to Observables (0) | 2022.10.24 |
[🌱SeSAC] Rx.playground 실행하는 방법 (1) | 2022.10.24 |