본문 바로가기

Swift/RxSwift

[🌱SeSAC] 마침내 피할 수 없는 아 .. 알엑스

728x90

한 줄 소감 : 알엑스 .. 잭 앤 휴와 함께라면 뿌실 수 있다.

 

RxSwift란?

ReactiveX를 도입한 Swift 전용 구현 라이브러리이다.

(이게 뭔데? 사실 .. 개념 자체보다 어떻게 구현되는지, 어떻게 동작되는지가 더 중요하다. 일단 넘어가자.)

 

 

RxSwift의 키워드

알엑스에서 주의해야 하는 키워드는 세가지이다.

  • Observer
    • 이벤트를 방출 -> 전달받는 패턴이다. 
    • 일종의 Notification처럼 동작한다. (알림을 보내고 .. 알림을 받는 식의 ..) 
    • Observable을 이용해서 이벤트를 보내면 
    • Observer을 통해 이벤트를 전달 받는다. 
  • Iterator
    • map, filter, reduce 등과 같은 메서드를 생각해보자. 
      • 이런 함수들의 주의할 점은 순서이다.
      • filter를 하고 reduce를 하는 것과 reduce를 하고 filter를 하는 것에 결과값의 차이가 있다.
    • 이런 식의 데이터의 흐름이 존재하는데 
    • RxSwift 역시 Iterator을 통해 데이터의 흐름을 관리하고 순차적으로 메서드를 실행할 수 있다. 
  • Functional Programming 

 

Observable - Observer 

간단하게 말하면,

  • Observable : 이벤트 방출, 전달 
  • Observer : 이벤트에 대한 처리 

 

예를 들어서 아래 두가지 상황이 있다고 가정하자.

ex) 로그인을 하는 상황 

  1. 사용자가 텍스트에 이름 입력하게 된다. (→ Obversable)
    1. 각 문자 입력
    2. → 상황에 대한 전달
    3. → ~ 입력 한다?(이벤트 보내는 중) 
  2. 입력값에 따른 결과를 처리한다. (→ Observer)
    1. 입력에 따른 버튼 활성화, 경고 문구의 색상 변화 등
    2. → 입력값에 따른 결과 반환(이벤트 받아서 상황에 맞는 결과 반환) 

 

ex) 유튜브 (구독)

  1. 유튜브에는 여러 채널이 존재한다. 
  2. 각 채널 주들이 각자의 채널에 영상을 업로드 하는 것 = 이벤트를 계속 보내는 것을 의미한다. (전세계의 채널 주인들은 영상 올리는 것에 대한 이벤트를 보낸다.)
  3. 이 중 하나의 채널을 구독한 경우, 아무리 여러 채널에서 이벤트를 보내도 구독한 채널에 대한 이벤트만 받을 수 있다. → 이벤트를 받을 객체는 따로 존재한다. 

 

이 두가지 상황에 대해서 알 수 있는 것은 아래와 같다.

✅ 이벤트를 보내는 객체와 이벤트를 받는 객체로 나뉘어져 있다는 것

✅ Observable이 많아도 Observer가 없다면 보내는 이벤트에 대한 처리를 할 수 없다. 

 

 

RxSwift Basic

Observable은 영상을 업로드하고 (유튜브를 생각해보면)

= 이벤트를 전달하고

= 계속 이벤트를 전달하고

 

Observer은 영상을 받아본다.
= 전달 받은 이벤트를 처리한다. (화면 전환, 알림창 등의)

= 계속 이벤트를 관찰하고 있어야 한다. 

*1:1 대응으로 보이지만, Notification처럼 여러개가 등록될 수 있다.
(일 대 다, 다 대 일, 다 대 다 등 ..)

 

🤔 만약 Observable에 Observer가 없다면? 
해당 옵저버블에서 이벤트를 보내도 이를 전달 받아 처리할 객체가 없기 때문에 Observable을 만든다면 Observer를 만들어야 한다.

🤔 만약 나중에 Observer가 생긴다면?
Observer가 생긴 시점 이후로 이벤트를 처리할 수 있다. 

 

 

이벤트의 종류 

Observable이 이벤트를 방출하고, Observer가 이벤트를 처리하는 코드라고 했을 때

여기서 말하는 이벤트는 크게 두가지 종류로 나눌 수 있다.

 

  1. 유한하게 방출할 수 있는 이벤트
  2. 무한하게 방출할 수 있는 이벤트 

 

무한한 이벤트

예를 들어 가로모드와 같은 이벤트를 생각해보자.

  • 세로 모드에서 가로모드로 바뀌게 된다면?
    • 이러한 이벤트는 한번도 발생하지 않을 수도 있지만, 여러번 (셀 수 없을 만큼) 발생할 수 있다.
    • 이러한 이벤트의 횟수를 제한할 수 없다. (= 이벤트에 대한 한계를 지을 수 없다.)
  • 주로 UI와 관련된 이벤트의 경우는 무한한 이벤트라고 할 수 있다.
  • 데이터의 흐름이 끝나지 않고 무한하게 발생한다.
  • Infinite Observable Sequences 

 

유한한 이벤트

그렇다면 어떤 경우에 유한하다고 할 수 있을까? 

  • 넷플릭스에서 오프라인으로 저장한 경우
  • 백업/복구를 한 경우 
  • 만약 위의 두가지 경우가 용량이 엄청 큰 경우라면? 
    • 한번에 이벤트를 처리하는 것이 어려울 것이다.
    • 그래서 조금씩, 점진적으로 이벤트를 처리하게 된다.

 

위의 이미지를 통해서 볼 수 있는 것처럼 점진적으로 이벤트가 처리되는 것을 볼 수 있다.

(NASA API에서 이미지를 다운로드 받게 되는 경우를 볼 수 있다.)

 

🚨 다운로드 버튼 누르는 것은 무한하다. (이는 사용자에게 인터렉션을 받는 작업이므로 UI와 관련된 작업이라고 할 수 있다.)

🚨 다운로드를 받는 하나의 과정에 대해서 유한하다고 할 수 있다.

 

이런 경우를 유한한 시퀀스라고 한다.

 

🤔 map, filter, reduce와 같은 고차함수를 사용한 옵저버블도 유한 시퀀스라고 볼 수 있다.

 

 

이벤트의 상황/상태 

용량이 큰 이미지를 다운로드 받을 때 과정은 아래와 같다.

  1. 점진적으로 다운로드를 실행한다. 
    1. 네트워크 연결이 유실되거나
    2. 다운로드 실패하거나
    3. 상태 코드 등의 오류로 다운로드가 되지 않는다면
    4. error의 형태로 반환된다/
  2. 성공적으로 다운로드가 완료되면, 이미지가 보일 것이다.

이벤트를 보내고 받는다. 로 끝나는 것이 아니라 하나의 이벤트 과정 안에 여러 상태가 존재하게 된다.

 

위와 같은 경우를 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

  1. Observable을 생성한다. (이벤트를 방출할 준비를 한다.) 보통, 구현되어 있는 Operator를 사용한다.
  2. Subscribe가 되면 Observable이 실행된다.
  3. next를 통해 이벤트(제스쳐, 인스턴스 등)을 emit한다.
  4. Life Cycle 도중에 오류가 발생한다면, error 이벤트를 / 정상적으로 이벤트가 완료된다면 completed를 notification 한다.
  5. deinit되는 시점, 즉 sequence가 종료되는 시점에 dispose된다.
  6. 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