⭐️ 개발/Rx
[Rx] Combine Operator
Combine Operator startWith concat merge combineLatest zip withLatestFrom sample switchLatest reduce -> transform 가장 마지막에 있음 startWith 옵저버블 시퀀스 앞에 새로운 요소를 추가 // MARK: - startWith : 옵저버블 시퀀스 앞에 새로운 요소를 추가 let num = [1,2,3,4,5] // 기본값이나 시작값 지정시 활용 Observable.from(num) .startWith(9999) // 2개 이상 연달아 사용 가능 .startWith(1111, 2222) .startWith(3333) .subscribe { print($0) } .disposed(by: bag) // Last In F..
[Rx] Transform Operator
Transform Operator toArray map compactMap flatMap flatMapLatest flatMapFirst concatMap buffer window groupBy scan (reduce까지) toArray 원본 옵저버블이 방출하는 모든 요소를 하나의 배열로 바꿔서 방출해줌 // MARK: - toArray : 원본 옵저버블이 방출하는 모든 요소를 하나의 배열로 바꿔서 방출해줌 let numbers = [1,2,3,4,5,6,7,8,9,10] let subject = PublishSubject() subject .toArray() // single로 변환, 하나의 요소로 변환 .subscribe { print($0) } .disposed(by: bag) subject.onN..
[Rx] Sharing Operator
Sharing Operator share multicast, Connectable Observable publish replay, replayAll refcount share let bag = DisposeBag() let source = Observable.create { observer in let url = URL(string: "https://tistory.com")! let task = URLSession.shared.dataTask(with: url) { (data, response, error) in if let data = data, let html = String(data: data, encoding: .utf8) { observer.onNext(html) } observer.onComp..
[Rx] Time Based Operator
Time Based Operator interval timer timeout delay delaySubscription interval // MARK: - interval 지정된 주기마다 정수를 방출 // period : 반복주기 // scheduler : 정수를 방출할 스케줄러 // 지정된 주기마다 정수를 계속해서 방출한다. 즉, 무한한 시퀀스를 생성하는 것! -> 직접 dispose를 해줘야 함 // int를 포함한 모든 정수형식을 사용가능하다. let i = Observable.interval(.seconds(1), scheduler: MainScheduler.instance) let subscription1 = i.subscribe { print("1 >> \($0)") } // 별도로 종료시키는..
[Rx] Conditional Operator
Conditional Operator amb 여러 옵저버블 중에서 가장 먼저 이벤트를 방출하는 옵저버블을 선택하는 것 right 옵저버블이 left 옵저버블보다 먼저 방출됐기 때문에 left 옵저버블은 무시되고, rigth 옵저버블만 구독된다. 많은 서버 연결 시도 중 가장 먼저 응답을 준 서버와 통신하고 싶은 경우 사용한다. let bag = DisposeBag() enum MyError: Error { case error } let a = PublishSubject() let b = PublishSubject() let c = PublishSubject() // 소스 옵저버블이 2개로 제한될 경우 a.amb(b) .subscribe { print($0) } .disposed(by: bag) a.onN..
[Rx] Filtering Operator
Filtering Operator ignoreElement elementAt skip take debounce throttle filter single distinctUntilChanged ignoreElement // MARK: - IgnoreElements next 이벤트를 필터링하는 연산자 let friends = ["소깡", "디온", "방구"] Observable.from(friends) .ignoreElements() .subscribe { print($0) } .disposed(by: bag) //completed elementAt // MARK: - elementAt 특정 인덱스에 위치한 요소를 제한적으로 방출하는 연산자 Observable.from(friends) .element(at: ..
[Rx] Create Operators
Create Operators just, of, from range, generate repeateElement deferred create just, of, from import RxSwift let disposeBag = DisposeBag() let element = "🎀" // MARK: - just, of, from 옵저버블 생성에 사용한느 가장 단순하고 기초적인 세가지 연산자 // just는 파라미터로 전달한 걸 그대로 전달한다. // 🎀 Observable.just("🎀") .subscribe { event in print(event) } .disposed(by: disposeBag) // [1, 2, 3] Observable.just([1, 2, 3]) .subscribe { event i..
[Rx Operator 시리즈] 4. flatMap / flatMapFirst / flatMapLatest
1. FlatMap 방출된 항목의 값이 바뀌면 새로운 항목을 방출한다. 원본 옵저버블이 방출한 값을 감시해서 최신값을 확인할 수 있다. 옵저버블로 변환되고 값이 업데이트 될 때마다 새로운 항목을 방출한다. 모든 옵저버블이 방출하는 걸 모아서 -> 최종적으로 하나의 옵저버블(Result Observable)을 리턴한다. 네트워크 호출에 자주 쓰인다. let redCircle = "🔴" let greenCircle = "🟢" let blueCircle = "🔵" let redHeart = "❤️" let greenHeart = "💚" let blueHeart = "💙" Observable.from([redCircle, greenCircle, blueCircle]) .flatMap { circle -> Obs..
[Rx] NSObject+Rx 라이브러리
disposeBag 속성을 자동으로 추가해 주는 라이브러리 let bag = DisposeBag() 이 코드를 안써도 된다 이거지!! https://github.com/RxSwiftCommunity/NSObject-Rx GitHub - RxSwiftCommunity/NSObject-Rx: Handy RxSwift extensions on NSObject, including rx.disposeBag. Handy RxSwift extensions on NSObject, including rx.disposeBag. - GitHub - RxSwiftCommunity/NSObject-Rx: Handy RxSwift extensions on NSObject, including rx.disposeBag. github..
[Rx Operator 시리즈] 3. Zip
combineLatest와 다른 점? : 클로저에게 중복된 요소를 전달하지 않고, 인덱스를 기준으로 짝을 맞춰서 전달. 첫 번째 요소는 첫 번째 요소와 결합 두 번째 요소는 두 번째 요소와 결합 세 번째 요소는 세 번재 요소와 결합 Indexed Sequencing이라고 함 결합할 요소가 없으면 방출하지 않음 let numbers = PublishSubject() let strings = PublishSubject() Observable.zip(numbers, strings) { "\($0) - \($1)" } .subscribe { print($0) } .disposed(by: disposeBag) numbers.onNext(1) strings.onNext("One") // next(1 - One) n..
[Rx Operator 시리즈] 2. CombineLatest
소스 옵저버블이 방출하는 최신 요소를 병합하는 combineLatest 연산자 소스 옵저버블들을 결합해 방출하는 최신 이벤트를 대상으로 연산자를 실행해 결과 옵저버블을 방출 enum MyError: Error { case error } let greetings = PublishSubject() let languages = PublishSubject() Observable .combineLatest(greetings, languages) { first, second -> String in return "\(first) \(second)" } .subscribe { print($0) } .disposed(by: disposeBag) greetings.onNext("Hi") languages.onNext("R..
[Rx Operator 시리즈] 1. map
map은 옵저버블이 배출하는 항목을 대상으로 함수를 실행하고 결과를 방출 map 연산자는 옵저버블이 방출하는 요소들을 대상으로 클로저를 실행하고 그 결과를 구독자에게 전달한다. 클로저 내에서 원하는 형식으로 바꿔서 리턴해 전달이 가능하다. let skills = ["Swift", "SwiftUI", "RxSwift"] Observable.from(skills) .map { $0.count } .subscribe { print($0) } .disposed(by: disposeBag) // 출력 next(5) next(7) next(7) let skills = ["Swift", "SwiftUI", "RxSwift"] Observable.from(skills) .map { "Hello, \($0)" } .su..
7. Traits - ControlProperty, ControlEvent, Driver
Traits은 UI에 특화된 옵저버블이다. 모든 작업은 Main Thread에서 작동해서 스케줄러를 지정할 필요가 없다. UI가 항상 올바른 Thread에서 동작하는 걸 보장한다. Traits을 구독하는 모든 구독자는 동일한 시퀀스를 구독한다. like share() Error Event를 전달하지 않는다. Traits의 종류로는 ControlProperty, ControlEvent, Driver, Signal이 있다. 이게 종류가 많은데 언제 뭘 쓰는지, 어떻게 적용해야 하는지가 어렵다. 어렵냐? 나도 어렵다. 이 글에서는 ControlProperty와 ControlEvent에 대해서 자세히 작성해보겠당.. Driver와 Signal은 나도 어렵당.. 1. ControlProperty ControlPr..
6. Binder
Binder 바인딩에는 데이터 생산자(Producer)와 데이터 소비자(Consumer)가 있다. - 생산자는 옵저버블이다. Observable 타입 전부가 다 생산자 - 소비자는 Label, ImageView, UIView 같은 UI Component 생산자가 생산한 데이터는 소비자에게 전달되어 데이터를 소비한다. 레이블은 전달 받은 텍스트를 레이블에 표시한다. 반대의 경우는 없다. (소비자가 데이터를 생산하는 경우는 없다는 것) 이게 말로 표현해둬서 어려울 수 있는데 코드를 보면서 빗대어 보면 이해가 쉽다. 그래서 앞뒤 맥락없이 Binder의 개념에 대한 설명없이 갑자기 코드를 들이밀고 설명을 해보자면 inputField.rx.editingDidEnd .map { UIColor.gray } .bind..
[Rx] Error Operator
Error Handling catch, catchAndReturn, retry 상황 : 옵저버블이 네트워크 요청을 처리하고, 구독자가 ui를 업데이트한다. 에러이벤트가 전달되면 구독이 종료돼서 ui를 업데이트 하는 코드가 실행되지 않음. Rx는 이 경우, 1. 첫 번째 방법으로, catch 연산자를 통해 next / completed event는 그대로 전달하지만error event가 전달되면 새로운 옵저버블로 바꿔서 전달한다. 특히, 네트워크 요청 코드에서 많이 사용한다. catch 연산자는 클로저를 파라미터로 받고, Error 이벤트는 클로저의 파라미터로 전달되고, 클로저는 새로운 Observable을 반환한다. catch 연산자는 클로저가 반환하는 Observable과 같은 Observable 값을..