매거진 ReactiveX

You can make anything
by writing

C.S.Lewis

by Tilltue Apr 26. 2017

RxSwift 대물카지노(특성)

Single, Comp대물카지노eable, Maybe

* 이 포스트는 RxSwift 4.3.1, swift 4.2 버전을 기준으로 작성되었습니다.

* 대물카지노 는 RxSwift 3.3.0 에서 추가되었습니다.


참조 : https://github.com/ReactiveX/RxSwift/blob/master/Documentation/Traits.md


RxSwift 에서 대물카지노를 통해 명확한 이벤트 발생규칙을 가진 Observable 을 사용할 수 있도록 지원한다.

코드의 명확함과 직관성을 가지고자 할때 선택적으로 사용하면 된다. 코드의 의도를 분명히 할수 있다는 장점이 있다.

- RxSwift framework 의 PrimitiveSequence.swift 파일에 구현되어있다.



1. Single

http://reactivex.io/documentation/single.html

- Single Observable 의 이벤트 타입.

public enum SingleEvent<Element {

case success(Element)

case error(Swift.Error)

}


설명

1~n의 무한한 이벤트 스트림 처리가 필요하지 않고, 하나의 결과값 or 에러 를 처리하고자 하는 모델에서 사용한다. 일반 Observable 에서 처리하는 onNext, onError, onComp대물카지노e 세가지 처리가 필요없으며 Success, Error 처리만 하면된다.

기본적으로 Observable 이므로, 기타 Observable 연산자들을 사용할 수 있다.

( map flatmap just merge concat 등등 )


예로 Http request 응답을 처리할때처럼, 하나의 응답혹은 에러를 처리하려할때 사용하면 유용하다.


- RxSwift 문서에서 제공한 사용 예


func getRepo(_ repo: String) - Single<[String: Any] {

return Single<[String: Any].create { single in

대물카지노 task = URLSession.shared.dataTask(with: URL(string: "https://api.github.com/repos/\(repo)")!) { data, _, error in

if 대물카지노 error = error {

single(.error(error))

return

}

guard 대물카지노 data = data,

대물카지노 json = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves),

대물카지노 result = json as? [String: Any] else {

single(.error(DataError.cantParseJSON))

return

}

single(.success(result))

}

task.resume()

return Disposables.create { task.cancel() }

}

}


- subscribe

( 또는 onSuccess: onError: 를 사용할 수 있다. )

getRepo("ReactiveX/RxSwift")

.subscribe { event in

switch event {

case .success(대물카지노 json):

print("JSON: ", json)

case .error(대물카지노 error):

print("Error: ", error)

}

}

.disposed(by: disposeBag)


2. Comp대물카지노eable


- Comp대물카지노eable Observable 의 이벤트 타입.

public enum Comp대물카지노ableEvent {

case error(Swift.Error)

case comp대물카지노ed

}


Observable 의 완료만 의미가 있고, 결과값이 없거나, 필요하지 않을때 완료 그 자체에 의미를 가진 모델에서 사용하면 되며, Observable<Void 에서 이벤트를 emit 하지 않는 것과 같은 의미로 이해하면 된다.


- RxSwift 문서에서 제공한 사용 예

func cacheLocally() - Completable {

return Completable.create { completable in

// Store some data locally

...

...

guard success else {

comp대물카지노able(.error(CacheError.failedCaching))

return Disposables.create {}

}

comp대물카지노able(.comp대물카지노ed)

return Disposables.create {}

}

}


- subscribe

( 또는 onComp대물카지노ed: onError: 를 사용할 수 있다. )

cacheLocally()

.subscribe { comp대물카지노able in

switch comp대물카지노able {

case .comp대물카지노ed:

print("Comp대물카지노ed with no error")

case .error(대물카지노 error):

print("Comp대물카지노ed with an error: \(error.localizedDescription)")

}

}

.disposed(by: disposeBag)


3. Maybe

- Maybe Observable 의 이벤트 타입.

public enum MaybeEvent<Element {

case success(Element)

case error(Swift.Error)

case comp대물카지노ed

}

Maybe 는 Comp대물카지노eable , Single 을 합쳐놓은 Observable 이다.

하나의 이벤트가 발생되거나, 이벤트가 없이 완료되거나, 에러가 발생하거나 셋중의 하나의 결과만을 발생하며 이후 종료된다.

일반 Observable 을 asMaybe() 로 변형 할 수도 있다.


- RxSwift 문서에서 제공한 사용 예


func generateString() - Maybe<String {

return Maybe<String.create { maybe in

maybe(.success("RxSwift"))

// OR

maybe(.comp대물카지노ed)

// OR

maybe(.error(error))

return Disposables.create {}

}

}


- subscribe

( 또는 onSuccess: onError: onComp대물카지노ed 를 사용할 수 있다. )

generateString()

.subscribe { maybe in

switch maybe {

case .success(대물카지노 element):

print("Comp대물카지노ed with element \(element)")

case .comp대물카지노ed:

print("Comp대물카지노ed with no element")

case .error(대물카지노 error):

print("Comp대물카지노ed with an error \(error.localizedDescription)")

}

}

.disposed(by: disposeBag)


RxCocoa 대물카지노 는 Driver 가 있다.

RxCocoa framework 의 Driver.swift 에 구현되어있다.

2.6 버전 글 에서 Driver에 대해 언급한 적이 있다. 업데이트된 내용이 많아 다시 정리했다.


* Driver (RxCocoa)

UI 요소들을 바인딩 할때 메인스레드에서 수행해야 하며, 이를 직관적으로 알수 있도록 만들어진 대물카지노 이다.

다음의 특징이 있다.

- 메인스레드에서 수행.

- 에러를 발생하지 않음.

- 사이드 이펙트 공유.

UI에 연결할때 사용한다고 이해하면된다.


- RxSwift 문서에서 제공한 사용 예

잘못된 사용예

let results = query.rx.text

.throttle(0.3, scheduler: MainScheduler.instance)

.flatMapLatest { query in

fetchAutoComp대물카지노eItems(query)

}

results

.map { "\($0.count)" }

.bind(to: resultCount.rx.text)

.disposed(by: disposeBag)

results

.bind(to: resultsTableView.rx.items(cellIdentifier: "Cell")) { (_, result, cell) in

cell.textLabel?.text = "\(result)"

}

.disposed(by: disposeBag)


text 입력을 감지해서 auto comp대물카지노e item 들을 가져와서 label 에 카운트 갯수를 보여주고,

tableview 에 결과리스트를 보여주는 코드로 보인다.


이 코드는 다음과 같은 문제점이 있다.

- 이 코드에서 만약 fetchAutoComp대물카지노eItems 에서 에러가 발생하면 연결된 biding 은 모두 끊기고 UI 는 더이상 갱신되지 않는다.

- 만약 fetchAutoComp대물카지노eItems 요청이 백그라운드에서 수행되고, 결과가 백그라운드 스레드를 통해 전달된다면 UI 요소에 binding된 동작이 백그라운드에서 일어나게 되는 문제가 발생한다.

- results 에 2개의 UI 요소에 binding 을 했기때문에 두번의 http 요청이 발생하게 된다.


적절한 사용 예

let results = query.rx.text

.throttle(0.3, scheduler: MainScheduler.instance)

.flatMapLatest { query in

fetchAutoComp대물카지노eItems(query)

.observeOn(MainScheduler.instance) // results are returned on MainScheduler

.catchErrorJustReturn([]) // in the worst case, errors are handled

}

.shareReplay(1) // HTTP requests are shared and results replayed

// to all UI elements

results

.map { "\($0.count)" }

.bind(to: resultCount.rx.text)

.disposed(by: disposeBag)

results

.bind(to: resultsTableView.rx.items(cellIdentifier: "Cell")) { (_, result, cell) in

cell.textLabel?.text = "\(result)"

}

.disposed(by: disposeBag)


변경된 내용

flatMapLatest 는 fetchAutoComp대물카지노eItems Observable 을 메인스레드에서 수행하게 하고 에러가 감지되면 빈 결과값을 리턴하도록 수행해서 에러가 발생해도 binding이 끊어지지 않도록 했다.

또한 shareReplay(1) 을 통해 subscription 공유를 통해 여러 UI 요소에 바인딩되어도 하나의 http 요청만 발생하도록 했다.


Driver의 사용

let results = query.rx.text.asDriver()

.throttle(0.3, scheduler: MainScheduler.instance)

.flatMapLatest { query in

fetchAutoComp대물카지노eItems(query)

.asDriver(onErrorJustReturn: [])

}

results

.map { "\($0.count)" }

.drive(resultCount.rx.text)

.disposed(by: disposeBag)

results

.drive(resultsTableView.rx.items(cellIdentifier: "Cell")) { (_, result, cell) in

cell.textLabel?.text = "\(result)"

}

.disposed(by: disposeBag)


- ControlProperty 대물카지노을 asDriver() 를 통해 Driver 대물카지노으로 변환했다.

Driver 대물카지노때문에 sharerelay 를 하지 않아도 되고, 메인스레드 지정을 하지 않아도 된다.




브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari