iOS/RxSwift

· iOS/RxSwift
RxBlocking은 바로 전 포스팅에서 정리했던 RxTest와 같은 TestScheduler는 없이 Observable의 Event방출을 검증하는 방법입니다. 단순히 Observable이 특정값들을 방출하는 것을 검증할 때는 RxTest가 아니라 RxBlocking만으로 충분할 것입니다. RxBlocking은 Observable의 next이벤트를 배열로 변환하는 방법을 제공하여, 해당 값을 TestAssertion으로 테스팅할 수 있도록 해줍니다. Observable에 .toBlocking()을 사용하면 Observable을 BlockingObservable로 전환해주고, BlockingObservable은 .toArray()를 통해 next이벤트들을 complete이벤트가 발생할 때까지 배열로 전환시..
· iOS/RxSwift
보통의 유닛테스트라면 지난 글에서처럼 각 메서드들의 Input에 따른 Output값을 XCTest의 XCTAssertion을 통해서 테스트코드를 작성하면 됩니다. XCTest와 Nimble 기능을 구현하는 것도 중요하지만, '구현된 기능이 의도한 대로 당연하게 동작하는가?'를 테스트해보는 테스트 코드의 작성도 중요합니다. 배포를 하기 전에 사전에 문제를 발견할 수 있는 좋은 swifty-cody.tistory.com 하지만 RxSwift로 작성한 코드의 유닛테스트는 어떻게 할까요? RxSwift에서 사용하는 Observable은 '값이 아니라 시퀀스'이기 때문에 XCTest로 바로 테스트를 작성하기 어려울 수 있는데, 이를 위해서 RxTest와 RxBlocking이 준비되어 있습니다. (우리 Rx는 계획..
· iOS/RxSwift
iOS 개발을 하면 반드시 마주하게 되는 패턴 중 하나는 Delegate 패턴입니다. Cocoa에서 Delegate는 보통 DataSource(셀 구현, 셀/섹션 개수, 높이 등)를 대신 구현하게 하거나, 비동기 응답(사용자의 셀 선택, Location 업데이트 등)을 받기 위한 메서드를 구현하도록 합니다. 위와 같은 Delegate 패턴을 Rx를 통해 사용할 수 있도록 만들어주는 방법이 바로 DelegateProxy입니다. DelegateProxy의 구현을 MKMapView를 예시로 보겠습니다. (0) Extension으로 HasDelegate를 받습니다. 이미 delegate가 있는 클래스를 대상으로 하기 때문에 Extension에 따로 구현해줄 것은 없습니다. extension MKMapView: ..
· iOS/RxSwift
RxSwift 정리글에 이어서 RxCocoa를 정리를 조금 해봅니다. RxSwift는 플랫폼에 구애받지 않고 익혀두면 어디에서도 적용할 수 있는 공통적인 Reactive 사양을 구현해 놓았다면, RxCocoa는 iOS 개발에 (아직은) 많은 부분을 차지하고 있는 Cocoa Framework에 좀 더 특화되어 도움을 주는 클래스들이 있습니다. 이는 UIKit들에 반응형 확장(.rx)를 추가해서 다양한 이벤트를 subscribe 할 수 있게 해 줍니다. .rx RxCocoa를 import 하면 UIKit의 요소들(UIButton, UISwitch, UITableView, ...)의 인스턴스에서 .rx 키워드를 통해 해당 UI의 동작을 Reactive 하게 처리할 수 있도록 해줍니다. UISwitch의 예시입..
· iOS/RxSwift
RxSwift 정리에 딱 한달이 걸렸네요. 노션에 혼자 정리해놨던 것을 옮겼을 뿐인데, 아무래도 혼자 보려고 적어놓은 것과 다른 사람들도 볼 수 있는 블로그글을 작성하는 건 똑같을 수가 없었기 때문에 설명과 예제를 좀더 신경쓰면서 글을 작성했던 거 같습니다. 사실 이런 블로그 글을 보는 것보다 개념을 잡을때는 곰튀김님의 강의를 보거나 Operator들은 ReactiveX 공식 문서에서 필요한 것을 찾아보는 게 더 낫지만. 그래도 누군가에게 도움이 될까 한번 정리해봤습니다. RxCocoa, RxViewController, RxFlow도 글을 써볼까싶지만 바로 하지는 않을 거 같습니다.(미래의 제가 언젠가 하겠죠?) 글을 작성하면서 썼던 예제들은 Playground로 작성되었고, 아래 깃헙에 올려놓았으니 필..
· iOS/RxSwift
share Operator를 언제 사용할지를 이해하기 위해서는 먼저 Observable의 기본특성을 이해해야 합니다. 이전 글(https://swifty-cody.tistory.com/56)에서 정리했지만, Observable은 정의해놓은 것만으로는 아무값도 방출이 되지 않고 subscribe을 했을 때부터 값을 방출합니다. // Create of let numObservable = Observable.of(1,2,3,4,5).debug("") // 출력 없음 subscribe를 하면? subscribe할 때마다 Element를 방출합니다. let numObservable = Observable.of(1,2,3,4,5).debug("") numObservable .subscribe() // 한번 subs..
· iOS/RxSwift
이번 글에서는 Time base의 Operator를 정리해봅니다. replay subscribe를 했을 때, replay대상이 이전에 방출했던 element를 buffer만큼 다시 방출시켜주는 Operator입니다. replay를 지정해주고 connect()를 호출해주어야 합니다. print("- - - - - replay - - - - -") let shinee = PublishSubject() let replay = shinee.replay(2) replay.connect() // replay와 같은 연산자들은 connect를 해주어야 함 shinee.onNext("링딩동 링딩동") shinee.onNext("링디기딩디기딩딩딩") replay .subscribe(onNext: { print($0) }..
· iOS/RxSwift
이번 글에서는 두개 이상의 Observable을 결합하기 위한 Combining Operator들을 정리해보려 합니다. zip zip은 묶인 Observable들의 결과값을 쌍으로 묶어서 내보내줍니다. 쌍이 맞지 않은 결과값은 쌍이 맞을 때까지 방출될 수 없게 됩니다. zip으로 묶이는 Observable들은 데이터 타입이 달라도 상관이 없습니다. print("- - - - - zip - - - - -") enum Whose { case mine case yours } let almond = Observable.of("HoneyButter", "Wasabi", "MintChoco", "Corn", "Buldak") let whose = Observable.of(.mine, .mine, .yours, .m..
· iOS/RxSwift
[RxSwift] Filtering operators [RxSwift] Relay - PublishRelay, BehaviorRelay, ReplayRelay [RxSwift] Subject - PublishSubject, BehaviorSubject, ReplaySubject, AsyncSubject [RxSwift] Create Operators (1) just, of, from, range, empty, never [RxSwift] Create Operators (2) create 그리고 D swifty-cody.tistory.com 지난 글에서는 값을 선택적으로 받기 위한 Filtering Operators를 정리해봤습니다. 이번 글에서는 받은 값을 가공하기 위한 Transforming Opera..
· iOS/RxSwift
[RxSwift] Relay - PublishRelay, BehaviorRelay, ReplayRelay [RxSwift] Subject - PublishSubject, BehaviorSubject, ReplaySubject, AsyncSubject [RxSwift] Create Operators (1) just, of, from, range, empty, never [RxSwift] Create Operators (2) create 그리고 Dispose [RxSwift] Create Operators (3) defer [RxSwift] Trait swifty-cody.tistory.com 지난글에서 정리한 Relay를 마지막으로, Observable, Subject, Relay까지 정리를 다 했습니다...
· iOS/RxSwift
이번엔 Subject에서 파생된 Relay의 정리글입니다. Relay를 설명하기 전에 Relay의 등장배경을 먼저 정리를 하자면. 우리는 RxSwift를 앞서 정리한 예제들과 같이 데이터를 다룰때 뿐만 아니라, iOS 앱을 개발할 때 UI와 바인딩을 하여 활용을 하게 될텐데요. 앞에서 배웠던 Observable, Subject들을 그대로 사용했을 때 문제가 발생할 수 있습니다. 바로 이들의 특징 때문인데요. Observable과 Subject는 error가 발생했을 때 시퀀스가 종료되고, 종료된 시퀀스는 재활용을 할 수가 없습니다. 시퀀스가 종료되면 UI와의 바인딩도 종료되어 더이상 동작을 하지 않게 됩니다. 그래서 error와 complete이벤트가 발생하지 않는, 절대 종료되지 않음이 보장이 되는 S..
· iOS/RxSwift
Observable은 create할 때부터, 어떻게 데이터를 방출할지 정해져 있는 시퀸스입니다. create된 Observable을 subscribe함으로써 observer는 값을 받거나 받은 값을 가공할 수만 있는 read-only와 같습니다. Subject는 Observable이자 Observer역할을 모두 할 수 있고, create 이후에도 Observable의 외부에서 동적으로 원하는 값을 추가할 수 있는 시퀀스입니다. Subject에는 PublishSubject, BehaviorSubject, ReplaySubject, AsyncSubject가 있는데, 주로 PublishSubject, BehaviorSubject가 많이 쓰입니다. 하나씩 정리해보겠습니다. PublishSubject 이름과 같이..
· iOS/RxSwift
Observable은 next, completed, error 세 가지 이벤트를 방출하는 타입인데요. 하지만 항상 저 세 가지 이벤트가 모두 필요한 것은 아닙니다. 그래서 RxSwift는 상황에 맞는 Observable의 변형들을 제공하는데 이를 Traits(특성)이라고 합니다. Single, Completable, Maybe 이렇게 세가지 Traits가 있습니다. Observable을 사용해도 되지만, 이 Traits들은 이름을 읽고서 좀 더 쉽게 흐름을 파악할 수 있도록 해 주고, API를 읽는 사람들에게 코드의 의도를 명확하게 전달하는 방법을 제공하는 것이 목적입니다. Single Single은 success(value), failure(error) 이벤트만 방출시킵니다. (error(error)이..
· iOS/RxSwift
Observable의 생성 Operator 마지막 글입니다(아마도). 첫번째 글에서는 just, of, from, range, empty, never 를 정리했고 두번째 글에서는 create를 정리했습니다. 이번에도 이전에 정리한 생성 Operator와 또다른 성격의 defer를 해봅니다. deferred defer로 생성된 observable은 다른 생성 operator들과 다르게, observer가 subscribe를 호출하면 그 때부터 observable을 생성시킵니다. 그래서 defer는 subscribe할 때마다 다른 observable을 생성시키는 Factory를 구현할 수 있습니다. print("----- deferred -----") let disposeBag = DisposeBag() /..
· iOS/RxSwift
이전 글에서는 Observable을 생성할 수 있는 just, of, from, range, empty, never operator들을 정리해봤습니다. 이번 글에서도 이어서 생성 operator를 정리해보려고 하는데, 앞서 정리한 것들과는 조금 다른 operator들을 다뤄봅니다. Create RxSwift의 Lifecycle을 정리한 글에서 Observable이 next, completed, error 이벤트를 방출시키는 타입이라고 했죠. Create는 각 이벤트들을 방출시키는 onNext, onCompleted, onError 를 직접 구현하는 방식입니다. print("----- create (1) -----") Observable.create { observer -> Disposable in obs..
SwiftyCody
'iOS/RxSwift' 카테고리의 글 목록