티스토리 뷰
ReactorKit으로 단방향 반응형 앱 만들기(전수열) 의 라이브 코딩 예제를 따라해본 것을 정리 -- !!
우선 ReactorKit에 대한 개념은 미디엄 과 슬라이드 에 잘 설명되어있습니다.
간단히 플로우만 보자면
1. View는 Action(사용자 입력 등)을 Reactor에게 전달한다
2. Reactor는 전달받은 Action에 따라 비즈니스 로직을 수행한다.
3. 그 후 Reactor는 상태를 변경하여 View에게 전달한다
Reactor를 좀 더 자세히 들여다보면 이런 그림입니다
Reactor는 Action이 들어오면 두 단계에 거쳐서 State를 변경하는 것을 볼 수 있습니다
1. mutate() 함수
- Action 스트림을 Mutation 스트림으로 변환하는 역할
- 이곳에서 네트워킹이나 비동기 로직 등의 사이드 이펙트를 처리한다.
그 결과로 Mutation을 방출하는데, 그 값이 reduce() 함수로 전달된다.
2. reduce() 함수
- 이전 상태와 Mutation을 받아서 다음 상태를 반환한다.
이제 예제 프로젝트를 만들어줍니다..!!
플러스랑 마이너스 버튼을 눌러서 value를 increase or decrease 시켜주는 예제입니다
[1] Reactor 만들기
CounterViewController는 ReactorKit에서 'View'에 해당하는 것이고 이 View에 대응되는 Reactor를 만들어줍니다
이렇게 Reactor프로토콜을 따르는 CounterViewReactor를 만들어주었습니다.
그리고 안의 값을 채워줍니다
1. Action
- 사용자 액션은 increase(플러스버튼누르기)와 decrease(마이너스 버튼 누르기)가 있는데, 이것을 정의합니다
(사용자가 위의 액션을 하면 Reactor에 increase 또는 decrease가 전달될 것입니다)
2. State
- 현재 값을 정의하는 value라는 것을 만들었습니다
3. Mutation
- Action과 State의 중간다리(?)
- increase라는 Action이 들어왔을 때는 value를 1 증가시켜줄거야 -> increaseValue
decraese라는 Action이 들어왔을 때는 value를 1 감소시켜줄거야 -> decreaseValue
이 두가지를 정의해줍니다
그 다음 mutate함수를 구현해줍니다
action을 받아서 mutation의 옵져버블을 리턴해주는 함수입니다
increase라는 action이 들어오면 increaseValue라는 mutation의 Observable을
decrease라는 action이 들어오면 decreaseValue라는 mutation의 Observable을 리턴해주게 해줍니다
그 다음, reduce 함수를 구현해줍니다.
이전 상태와 뮤테이션을 받아서 다음 상태를 반환하는 함수입니다.
mutation이 increaeValue이면 이전상태에서 1을 증가시킨 새로운 상태를 리턴해주고
mutation이 decreaseValue이면 이전 상태에서 1을 감소시킨 새로운 상태를 리턴해줍니다
이렇게 Reactior 구현이 끝났습니다!
[2] 나의 뷰를 ReactorKit의 View로 만들기
ReactorKit의 View로 만들려면 View라는 프로토콜을 따르게 해줘야합니다
스토리보드를 사용하니까 StoryboardView 프로토콜을 따르게 해줍니다.
disposeBag을 구현해주고
bind라는 함수의 구현해줍니다 (reactor 타입을 아까 만든 CounterViewReactor로 해줍니다)
그 다음 bind함수에서 사용자 액션을 reactor의 action으로 바인딩 해줍니다
increaseButton이 탭되면 increase 액션으로 변환하여 reactor의 action에 바인딩해주겠다
decreaseButton이 탭되면 decrease 액션으로 변환하여 reactor의 action에 바인딩해주겠다
라는 의미의 코드입니다
그럼 Reactor에서 일어나는 일을 정리해보자면..!
1. increase 버튼과 decrease버튼이 각각 눌렸을 때 각각 increase, decrease 액션이 reactor에 전달이 된다.
2. 그러면 mutaion 함수가 먼저 실행이 되고 그 다음 reduce가 실행이 된다.
3. 그 결과로 나온 새로운 상태가 뷰에 전달 되게 된다
그리고 이런식으로 주는 상태를 뷰에 바인딩(또는 렌더링)합니다.
이제 reactor가 새로운 state를 주면, state안에 있는 value로 valueLabel을 업데이트 시켜주게 되었습니다..!
(다만 value가 이전 값이랑 다르다면)
이제 view도 끝-!
[3] View에 Reactor 넣어주기
하지만 여기까지 했다고 작동이 되지 않습니다.
bind 메소드는 View의 reactor에 새로운 값이 들어왔을 때만 호출되기 때문입니다..!
그래서 appdelegate로 이동합니다 (저는 xcode11이여서 scenedelgate로)
이렇게 View에 Reactor를 넣어주면 bind 함수가 실행이 됩니다.
[추가] 비동기 같은 상황을 만들고 IndicatorView를 추가하여 ReactorKit의 간결함을 더 느껴보자
그 다음..!! 우리는 비동기에서 처럼 1초후 값이 증가, 감소하게 만들어줄 것이고 1초 동안 떠있을 인디케이터를 만들어봅시당..!!!!
인디케이터 뷰를 추가해주고
State에 isLoading 프로퍼티를 추가합니다
Mutation에도 setLoading을 추가합니다
로딩이 어떻게 시작하는 지는 뷰는 몰라도 된다!! 그래서 Action은 건들지 않습니다!!!
이제 mutate 함수의 increase를 수정해줍니다
concat 오퍼레이터는 안에 넣어준 친구들을 순차대로 실행시켜주는 오퍼레이터 입니다-!
이것을 이용하여 setLoading을 true로 해주고 1초 딜레이를 줘서 값을 증가시킨 다음 (비동기랑 비슷하게 하기 위해서) setLoading을 false로 해줍니다-!
decrease도 동일하게 해줍니다
새로운 Mutation이 추가되었으니 reduce에서도 그에 맞는 처리를 해줍니당-!
이제 CounterViewController의 bind함수에 가서
isLoading 상태도 UI에 바인딩해줍니다-! ( 값이 바뀔 때만 UI 업데이트 시켜주기 위해 distinctUntilChanged 썼음 )
이렇게 ReactorKit을 이용하면 복잡한 비동기처리도 간결하게 할 수 있습니다
짱짱!!!
전체코드:
https://github.com/eunjin3786/ReactorKitPractice
'🍏 > Architecture, DesignPattern' 카테고리의 다른 글
[DI] 의존성 주입(Dependency Injection) 을 해주는 세가지 방법 (0) | 2020.01.17 |
---|---|
[Architecture] iOS 앱 아키텍쳐 2탄 (ReactorKit/RIBs/Clean Architecture/CleanSwift) (0) | 2020.01.16 |
[MVVM] MVVM 의 다양한 옵션들 (5) | 2019.07.04 |
[MVVM] 프로젝트를 MVC -> MVVM으로 리팩토링해보자 (0) | 2019.03.31 |
[Architecture] iOS 앱 아키텍쳐 1탄 (MVC/MVVM/VIPER/MVC-C/MVVM-C) (1) | 2019.03.25 |
- Total
- Today
- Yesterday
- Django Heroku Scheduler
- cocoapod
- Sketch 누끼
- flutter 앱 출시
- DRF APIException
- Flutter 로딩
- Python Type Hint
- Flutter Text Gradient
- 플러터 얼럿
- METAL
- flutter dynamic link
- flutter deep link
- Flutter Spacer
- 장고 URL querystring
- PencilKit
- drf custom error
- SerializerMethodField
- Watch App for iOS App vs Watch App
- 플러터 싱글톤
- Dart Factory
- Django FCM
- flutter build mode
- ipad multitasking
- ribs
- 구글 Geocoding API
- Django Firebase Cloud Messaging
- 장고 Custom Management Command
- Flutter getter setter
- github actions
- Flutter Clipboard
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |