RxSwift/Cocoa - Traits

JSLee·2022년 3월 8일
0

RxSwift/Cocoa 가 가지고 있는 Traits 의 대해 가벼운 설명

RxSwift

1. Single

Observable 과 흡사하지만 무한한 수를 Emit 하는것과 다르게 Single 은 하나의 값 또는 Error 만 Emit 한다.

  • .Success 는 Observable 의
    [ onNext & onCompleted ] 가 더해진 Emit Event 라고 볼수있다.

  • 기본적인 값을 산출하는 Async 적 연산에도 유용하고 응답/오류 만 return 하는 HTTP Request 응답을 처리할때 처럼 단일요소의 응답 , 에러를 처리할때 유용함..

  • 기본적으로 Single 또한 Observable 의 변형이라고 볼수 있고 Observable 의 Operator 들을 사용할수 있다.


예시 코드

func getRequest(url: String?) -> Single<Bool> {
// Bool 타입의 Single 생성

    return Single<Bool>.create { single in
        
guard let url = url else {

// 매개변수로 들어온 url 이 nill 일경우 single은 error를 방출한다.
// 생명주기 종료
            single(.error(NSError.init(domain: "error", code: -1, userInfo: nil)))
            return Disposables.create()
        }
// 그렇지 않을 경우 if 를 통해서 조건에 맞는 값을 success 할수 있다.

        if url == "https://www.google.com" {
            single(.success(true))
        } else {
            single(.success(false))
        }

        return Disposables.create()
    }
}
 
getRequest(url: ) 
	.subscribe(onSuccess : { success in 
}.onError : { error in 
})
.disposed(by : disposBag)

2.Completable

  • Element를 Emit 하지 않고 Error / Completed 만 Emit 하는 Observable 의 변형이다.

  • 성공적인 Completd 여부만 파악해야 할경우 사용하기 좋다.(DB에 Data 저장 여부 등등)

  • Completable 은 다른 변형과 다르게 Observable 을 Completable 로 변경할수 없다.


예시코드

let disposeBag = DisposeBag()
let completable = Completable.create { event in 
	let someError = false 
	if someError {
		event(.error(Error))
 	}else {
		event(.completed) 
	}
	return Disposables.create { 
		print(DDD)
	}
}
// 사용
	completable.subscribe(onCompleted : { 
		print(Event)  
	}) { (error) in 
		print(“error”)
	},disposed(by: disposBag )

3. Maybe

  • Success , Completed , Error Event 를 Emit 한다.

  • Element 를 Emit 합니다.

  • 단일요소를 내보내거나 요소를 내보내지 않고 Completd 하거나 Error 를 내보낼수도 있습니다.

  • 캐시에서 데이터를 가져올때 사용한다.

private let disposeBag = DisposeBag()
    public enum SomeError: Error {
       case genericError(String)
    }

    let maybe = Maybe<String>.create { event in
        let dividend = Int.random(in: 20...30)
        let divisor = Int.random(in: 0...5)
            
        if divisor == 0 {
           event(.error(SomeError.genericError("Divisor is 0")))
        } else {
           let value = dividend / divisor
           if value > 5 {
              event(.success("Number is greater than 5"))
           } else {
              event(.completed)
           }
        }
        return Disposables.create {
            print("Disposed trait resources")
        }
    }

// 사용

    maybe.subscribe(onSuccess: { (value) in
          print("Value is \(value)")
    }, onError: { (err) in
          print("Error is \(err.localizedDescription)")
    }) {
          print("Completed Event")
    }.disposed(by: disposeBag)

RxCocoa

기본적으로 Rxcocoa 는 UI 작업시 코드를 쉽고 직관적으로 작성 가능하다.
cocoa 의 traits 에는 여러 공통점이 있다.

  • Error를 Emit 하지 않는다.

  • MainScheduler 에서 Subscribe 된다.

  • Signal 제외 Share 가능

Driver

  • Driver 는 Error 가 없습니다(Emit X)
  • MainScheduler 에서 발생합니다.
  • Share 를 공유합니다.

Driver 는 id , pw 등 입력에 따라서 UI 가 동적으로 변경 되어야 할때 사용하기 적절하다.

       let idVaild = idTF.rx.text.orEmpty.map(idCheck(_:))
        let pwVaild = pwTF.rx.text.orEmpty.map(pwCheck(_:))
        
//        Observable.combineLatest(idVaild, pwVaild) { $0 && $1 }
//        .observe(on: MainScheduler.instance)
//        .catchAndReturn(false)
//        // completd / dispose 났을경우 처리를 못하기위해 작성되는 코드
//        .materialize() // completd / dispose 를 무시
//        .dematerialize()
//        .subscribe(onNext: {
//            print($0)
//        }).disposed(by: disposeBag)
        
        Observable.combineLatest(idVaild, pwVaild) { $0 && $1 }
        .asDriver(onErrorJustReturn: false) // completd / error 무시
        .drive(onNext: { // MainThread 로 변경됨
            print($0)
        }).disposed(by: disposeBag)

길었던 코드가 Driver 로 많이 줄어들었다.

Signal

Driver 와 흡사하다.

  • Error 를 Emit 하지 않는다
  • MainScheduler 에서 작동한다.
  • Observer 에게 Replay 하지 않는다.
  • Subscribe 이후 Emit 되는 Event 를 받는다.
public func asSignal(onErrorRecover: @escaping (_ error: Swift.Error) -> Signal<Element>) -> Signal<Element> {
        let source = self
            .asObservable()
            .observeOn(SignalSharingStrategy.scheduler)
            .catchError { error in
                onErrorRecover(error).asObservable()
            }
        return Signal(source)
    }

ControlEvent

  • 절대 실패하지 않는다.

  • Subscriber에게 초긱밧을 전송하지 않는다.

  • base가 deallocated될 때 complete된다.

  • Main scheduler에서 subscribe되는 것이 보장된다. (subscribeOn(ConcurrentMainScheduler.instance))

  • MainScheduler.instance 에서 event가 전달된다.

    ControlProperty

  • Ui element 의 property 를 나타내기 위함 특성이다.

  • 실패가 없다.

  • Share (replay : 1 ) 처럼 행동한다.

  • 메인 스케줄러에서 구독된다.

profile
iOS/Android/FE/BE

0개의 댓글