Skip to content

RxSwift 시작하기 위해 시작시점의 알아야될 것을 정리 및 셈플링 해보는 저장소입니다.

License

Notifications You must be signed in to change notification settings

ClintJang/sample-rxswift-beginning

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

78 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RxSwift Beginning Sample

RxSwift 공부하자!

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로 대화할 수 있습니다. (러닝커브가 이해하면.. 높은 만큼 대화에 재미가 있습니다.)

단점

  • 러닝 커브가 높습니다.

링크

좋은 블러그

ClintJang
마기님
tilltue님
민소네님
Kanghoon님
그 외

어떻게 시작을 해야될까?

어떻게 시작을 어떻게 해야될지 모르겠습니다. 
어떤 라이브러리를 기본으로 가져가서 프로젝트를 생성하며, 
그걸 기반으로 기본 UI를 해보고, 
네트워크 활용을 해보면 기초적인 개념은 익힐 것 것 같아서 .. 
이런 순서로 기본 기능들을 사용해 나가면 되지 않을 까 싶습니다. 

사용할 라이브러리

코어

  • RxSwift : 스위프트 버전의 RX
  • RxCocoa : 기존 Cocoa 프레임 워크를 Rx로 래핑한 프래임워크

네트워크

아직은 적용한 셈플은 없음.

  • 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이 해지됩니다.
  • 해지가 안되면 메모리 릭이 발생하겠죠.

PublishSubject

구독 이후에 소스 Observable(들)이 배출한 항목들만 옵저버에게 배출합니다.

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

  • JustViewController.swift

     .. (중략) ..
     
     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

  • FromViewController.swift

     .. (중략) ..
     
     Observable.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

  • RangeViewController.swift

     .. (중략) ..
     
     Observable.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

  • DeferredViewController.swift

     .. (중략) ..
             
     let deferred = Observable<String>.deferred {
         
         // just("defer")의 실행을 늦춰보자!!
         Observable<String>.just("defer").debug()
     }
         
     // 딜레이 시키고 싶은 시간을 정하자
     let delayTime = 3.0
     print("== \(delayTime) 초 뒤에 subscribe 를 실행 할 것이고")
     print("== 그때!! Observable<String>.just(..).debug() 가 실행 될 것입니다.")
     print("\n\n")
     
         
     // 3초 뒤에 "Observable<String>.just("defer").debug()" 실행
     DispatchQueue.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

  • IntervalViewController.swift

     .. (중략) ..
     
     print("===============================")
     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

  • TimerViewController.swift

     .. (중략) ..
     print("===============================")
     print("첫번째 Timer 실행")
     print("서브스크라이브 되서, 2초 후 부터 실행")
     print("\n\n")
         
     let intervalFirst = 2 // 2초에 한번씩
         
     Observable<Int>.timer(RxTimeInterval(intervalFirst), scheduler: MainScheduler.instance)
         //            .debug()
         .subscribe({ print("첫번째:\($0)") })
         .disposed(by: disposeBag)
         
     print("===============================")
     print("두번째 Timer 실행")
     print("서브스크라이브 되서, 3초 후 에 실행")
     print("\n\n")
         
     let intervalSecond = 3 // 3초에 한번씩
         
     Observable<Int>.timer(RxTimeInterval(intervalSecond), scheduler: MainScheduler.instance)
         .map({ $0 + 1000 }) // 1000, 1001, 1002...
         .subscribe({ print("두번째:\($0)") })
         .disposed(by: disposeBag)
         
     print("===============================")
     print("\n\n")
     .. (중략) ..

Repeat (RepeatElement)

http://reactivex.io/documentation/operators/repeat.html

.. 아직

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

Filter

http://reactivex.io/documentation/operators/filter.html

Zip

http://reactivex.io/documentation/operators/zip.html

Of

아직

아직

아직

Concat

http://reactivex.io/documentation/operators/concat.html

  • ConcatViewController.swift

     .. (중략) ..
     let firstSequence: Observable<Int> = Observable.range(start: 1, count: 5)
     let secondSequence: Observable<Int> = Observable.from([6,7,8,9,10])
     let thirdSequence: Observable<Int> = Observable.of(11, 12, 13, 14, 15)
         
     let _ = Observable.concat(firstSequence, secondSequence, thirdSequence)
         .subscribe(
             onNext: { print($0) },
             onError: { print($0) },
             onCompleted: { print("onCompleted") }) { print("onDisposed") }
         .disposed(by: disposeBag)
     .. (중략) ..

.. 계속 공부합시다.

About

RxSwift 시작하기 위해 시작시점의 알아야될 것을 정리 및 셈플링 해보는 저장소입니다.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages