sample-rxswift-beginning
sample-rxswift-beginning copied to clipboard
RxSwift 시작하기 위해 시작시점의 알아야될 것을 정리 및 셈플링 해보는 저장소입니다.
RxSwift Beginning Sample
Rx : Reactive eXtensions 리엑티브 프로그래밍 패러다임이고, 데이터 흐름과 그 데이터의 변경에 따라 전달 되는 것을 중요시 생각하는 패러다임 같습니다.
Rx는 Observable 흐름을 가지고, 비동기 프로그래밍을 하기 위한 API 입니다.관련 어려운 단어!
Reactive Programming (RP)
Functional + RX = Functional Reactive Programming(FRP)
Language-Intergrated Query (LINQ)
왜 이리 공부하기 힘들지?
ReactiveX
RxSwift 셈플링을 하며 기능 익히기를 위한 레파지토리입니다.
셈플
테스트 소스를 작성하면서 공부를 하고 있습니다.
아직은 미흡하죠 .. 계속 수정중
첫 화면 (계속 공부하며 수정 중) | 11. 구구단을 공부해 볼까요? |
---|---|
![]() |
![]() |
장점
Rx
에겐 특별한 것이 있다.
- ** ☆ Rx에겐 특별한 것이 있다. ☆ ** : 특별합니다.!!
- 높은 가독성이 있습니다.
- 코드가 기존 방식에 비해 간결해 진다고 합니다.
- 유지보수에 좋습니다.
- 기획 변동에 유연하다고 합니다.
- 하나의 방식으로 비동기 처리를 합니다.
- NotificationCenter, Delegate, KVO, GCD .. 등.. Observable로 단일화 됩니다.
- 쉬운 비동기 코드
- 테스트 하기 좋습니다.
- 쉽게 사용할 수 있는 좋은 아키텍쳐들도 있습니다.
- 회사에 안드로이드, 프론트 모두 RX로 되어있다면, 모두가 RX로 대화할 수 있습니다. (러닝커브가 이해하면.. 높은 만큼 대화에 재미가 있습니다.)
단점
- 러닝 커브가 높습니다.
링크
- FRP의 구현체 : http://reactivex.io/
- https://github.com/ReactiveX
- 사용/활용법을 알아야죠? : http://www.rxmarbles.com/
- 필요한 오퍼레이터 들이 있고, 이해하기 좋게 조작해 볼 수 있습니다.
좋은 블러그
ClintJang
마기님
tilltue님
민소네님
Kanghoon님
그 외
- https://pilgwon.github.io/blog/2017/09/21/why-rxswift.html
- http://mobicon.tistory.com/467
어떻게 시작을 해야될까?
어떻게 시작을 어떻게 해야될지 모르겠습니다. 어떤 라이브러리를 기본으로 가져가서 프로젝트를 생성하며, 그걸 기반으로 기본 UI를 해보고, 네트워크 활용을 해보면 기초적인 개념은 익힐 것 것 같아서 .. 이런 순서로 기본 기능들을 사용해 나가면 되지 않을 까 싶습니다.
사용할 라이브러리
코어
네트워크
아직은 적용한 셈플은 없음.
- RxAlamofire : Swift Alamofire를 RxSwift로 감싼 HTTP 네트워킹 라이브러리
기본 용어
Observable
ReactiveX에서 Observer는 Observable를 구독합니다. Observable이 배출하는 하나 또는 연속된 항목에 Observer는 반응합니다. Observable이라는 객체를 활용해서 내보내고, 관찰 및 구독해서 원하는 개발을 가능하게 하여주죠.👍

- 데이터 발행자 : 가장 핵심적인 개념이며, 이벤트를 시간의 흐름에 따라 전달하는 전달자 입니다.데이터의 변화가 발행하는 데이터 소스 입니다.
- 비동기적으로 다수의 이벤트를 다루는 방법입니다.
- 옵저버 패턴의 확장이라 생각하면 됩니다.
-
옵저버블
(데이터 발행자
)은 이벤트를옵저버
(데이터 수신자
)에 전달합니다. -
Hot Observable
,Cold Observable
가 있습니다.- 콜드 옵저버블 의 개념이 있습니다. : 누군가 자신을 구독해야 Lazy evaluation(느긋한 계산법)이 되서 이벤트를 발생시키는 개념
- 콜드 옵저버블은 구독(subscribe())하지 않으면 데이터를 발행하지 않습니다.
- 핫 옵저버블은 구독과 관계없이 데이터를 발행합니다.
disposable, disposeBag
해지 시키는 역활을 하죠.
- subscribe(구독하다)가 반환해 주는 것이 disposable(일회용)
- disposeBag 은 disposable 들을 담아두는 것을 말합니다.
- 만약 해지 하고 싶은 대상의 disposeBag에 담으면, 그 대상이 메모리 해지 될때(dealloc) 담겨있는 disposable이 해지됩니다.
- 해지가 안되면 메모리 릭이 발생하겠죠.
Subject
PublishSubject
BehaviorSubject
옵저버가 BehaviorSubject를 구독하기 시작하면, 옵저버는 소스 Observable이 가장 최근에 발행한 항목(또는 아직 아무 값도 발행되지 않았다면 맨 처음 값이나 기본 값)의 발행을 시작하며 그 이후 소스 Observable(들)에 의해 발행된 항목들을 계속 발행합니다.

ReplaySubject
옵저버가 구독을 시작한 시점과 관계 없이 소스 Observable(들)이 배출한 모든 항목들을 모든 옵저버에게 배출합니다.

Relay
Subject를 Wrapping 하고 있고, dispose 되기 전까지 계속 작동하는 특징이 있죠.
PublishRelay
BehaviorRelay
~~Variable~~ : DEPRECATED
~~Variable~~ => BehaviorRelay
Operator
Creating Observables
https://github.com/ClintJang/sample-rxswift-beginning/blob/master/README.md#creating-observables
Create
http://reactivex.io/documentation/operators/create.html

Just
http://reactivex.io/documentation/operators/just.html

-
. (중략) .. Observable.just(1) .subscribe(onNext:{ print($0) }, onError: { print($0) }, onCompleted: {print("onCompleted")}) .disposed(by:disposeBag) Observable.just("안녕하세요.") .subscribe(onNext:{ print($0) }, onError:{ print($0) }, onCompleted:{ print("onCompleted")}) .disposed(by: disposeBag) Observable.just([1,2,3,4]) .subscribe(onNext:{ print($0) }, onError:{ print($0) }, onCompleted:{ print("onCompleted")}) .disposed(by: disposeBag) let service: Observable<Int> = Observable.just(99) service.subscribe(onNext:{ print($0) }, onError:{ print($0) }, onCompleted:{ print("onCompleted")}) .disposed(by: disposeBag) .. (중략) ..
From
http://reactivex.io/documentation/operators/from.html

-
. (중략) .. bservable.from([1,2,3]) .subscribe(onNext:{ print($0) }, onError: { print($0) }, onCompleted: {print("onCompleted")}) .disposed(by:disposeBag) Observable.from(["기억","니은","디긋", "ㅎㅎㅎ"]) .subscribe(onNext:{ print($0) }, onError: { print($0) }, onCompleted: {print("onCompleted")}) .disposed(by:disposeBag) . (중략) ..
Range
http://reactivex.io/documentation/operators/range.html

-
. (중략) .. bservable.range(start: 1, count: 4) .subscribe(onNext: { print("onNext::\($0)") }, onError: { print($0)}, onCompleted: { print("onCompleted") }) .disposed(by: disposeBag) . (중략) ..
Defer (Deferred)
http://reactivex.io/documentation/operators/defer.html

-
. (중략) .. et deferred = Observable<String>.deferred { // just("defer")의 실행을 늦춰보자!! Observable<String>.just("defer").debug() / 딜레이 시키고 싶은 시간을 정하자 et delayTime = 3.0 rint("== \(delayTime) 초 뒤에 subscribe 를 실행 할 것이고") rint("== 그때!! Observable<String>.just(..).debug() 가 실행 될 것입니다.") rint("\n\n") / 3초 뒤에 "Observable<String>.just("defer").debug()" 실행 ispatchQueue.main.asyncAfter(deadline: .now() + delayTime) { [weak self] in if let strongSelf = self { deferred.subscribe(onNext:{ print($0) }) .disposed(by: strongSelf.disposeBag) } . (중략) ..
Interval
http://reactivex.io/documentation/operators/interval.html

-
. (중략) .. rint("===============================") print("첫번째 Interval 실행") print("서브스크라이브 되서, 2초 후 부터 반복") print("\n\n") let intervalFirst = 2 // 2초에 한번씩 Observable<Int>.interval(RxTimeInterval(intervalFirst), scheduler: MainScheduler.instance) .subscribe({ print("첫번째:\($0)") }) .disposed(by: disposeBag) print("===============================") print("두번째 Interval 실행") print("서브스크라이브 되서, 3초 후 부터 반복, 5회만 반복") print("\n\n") let intervalSecond = 3 // 3초에 한번씩 Observable<Int>.interval(RxTimeInterval(intervalSecond), scheduler: MainScheduler.instance) .map({ $0 + 1000 }) // 1000, 1001, 1002... .take(5) // 5회 .subscribe({ print("두번째:\($0)") }) .disposed(by: disposeBag) print("===============================") print("\n\n") . (중략) ..
Timer
http://reactivex.io/documentation/operators/timer.html

-
. (중략) .. rint("===============================") rint("첫번째 Timer 실행") rint("서브스크라이브 되서, 2초 후 부터 실행") rint("\n\n") et intervalFirst = 2 // 2초에 한번씩 bservable<Int>.timer(RxTimeInterval(intervalFirst), scheduler: MainScheduler.instance) // .debug() .subscribe({ print("첫번째:\($0)") }) .disposed(by: disposeBag) rint("===============================") rint("두번째 Timer 실행") rint("서브스크라이브 되서, 3초 후 에 실행") rint("\n\n") et intervalSecond = 3 // 3초에 한번씩 bservable<Int>.timer(RxTimeInterval(intervalSecond), scheduler: MainScheduler.instance) .map({ $0 + 1000 }) // 1000, 1001, 1002... .subscribe({ print("두번째:\($0)") }) .disposed(by: disposeBag) rint("===============================") rint("\n\n") . (중략) ..
Repeat (RepeatElement)
http://reactivex.io/documentation/operators/repeat.html
.. 아직
Transforming Observables
Scan
http://reactivex.io/documentation/operators/scan.html

Map
http://reactivex.io/documentation/operators/map.html

FlatMap
http://reactivex.io/documentation/operators/flatmap.html

ConcatMap
Filtering Observables
Filter
http://reactivex.io/documentation/operators/filter.html

Combining Observables
Zip
http://reactivex.io/documentation/operators/zip.html

Of
Error Handling Operators
아직
Observable Utility Operators
아직
Conditional and Boolean Operators
아직
Mathematical and Aggregate Operators
Concat
http://reactivex.io/documentation/operators/concat.html
-
. (중략) .. et firstSequence: Observable<Int> = Observable.range(start: 1, count: 5) et secondSequence: Observable<Int> = Observable.from([6,7,8,9,10]) et thirdSequence: Observable<Int> = Observable.of(11, 12, 13, 14, 15) et _ = Observable.concat(firstSequence, secondSequence, thirdSequence) .subscribe( onNext: { print($0) }, onError: { print($0) }, onCompleted: { print("onCompleted") }) { print("onDisposed") } .disposed(by: disposeBag) . (중략) ..
.. 계속 공부합시다.