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 파일에 구현되어있다.
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)
- 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)
- 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에 대해 언급한 적이 있다. 업데이트된 내용이 많아 다시 정리했다.
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 를 하지 않아도 되고, 메인스레드 지정을 하지 않아도 된다.