반응형
이번엔 RxSwift의 Trait들에 대해 알아보았습니다.
Trait
Trait은 Observable을 좀 더 안정성있고 의미있게 표현하기 위한 일종의 Syntax Sugar입니다. 그 종류로는 Single, Completable, Maybe가 있습니다. Observable을 좀 더 좁은 범위로 제한하여 제공함으로써 코드를 더 명시적으로 표현하는 것이죠.
일반적으로 Trait은 아래와 같이 단순히 read-only Observable의 wrapper 형태로 구성되어 있습니다. 이렇게 Observable에 대한 접근을 제한해놓고 내부에 존재하는 Observable를 조정하여 일부 기능에 특화된 형태로 사용자에게 제공합니다.
struct Single<Element> {
let source: Observable<Element>
...
}
Single
- .success(value) 혹은 .error 이벤트만을 방출합니다. .success(value)는 .next와 .completed가 합쳐져 있는 형태라고 생각하시면 됩니다. 성공 또는 실패로 한번에 확인할 수 있는 1회성 프로세스에 적절합니다. (ex. 데이터 다운로드, 디스크 데이터로딩)
- asSingle() 메서드를 통해 아무 Observable을 Single로 변환시켜서 확인할 수 있습니다.
- 생성과 사용은 Observable과 유사합니다. 아래 예제를 봅시다.
func getRepo(_ repo: String) -> Single<[String: Any]> {
return Single<[String: Any]>.create { single in
let task = URLSession.shared.dataTask(with: URL(string: "https://api.github.com/repos/\(repo)")!) { data, _, error in
if let error = error {
single(.error(error))
return
}
guard let data = data,
let json = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves),
let result = json as? [String: Any] else {
single(.error(DataError.cantParseJSON))
return
}
single(.success(result))
}
task.resume()
return Disposables.create { task.cancel() }
}
}
- subscribe로 이를 활용할 수 있습니다.
- SingleEvent는 .success 혹은 .error만을 제공합니다.
getRepo("ReactiveX/RxSwift")
.subscribe { event in
switch event {
case .success(let json):
print("JSON: ", json)
case .error(let error):
print("Error: ", error)
}
}
.disposed(by: disposeBag)
Completable
- .completed 혹은 .error만을 방출하며 그 외에 어떠한 값도 방출하지 않습니다. 특정 처리가 제대로 완료되었는지만 확인하고 싶을 때 많이 사용합니다. (ex. 파일 쓰기)
- observable이 값요소를 방출한 이상, 이를 Completable로 변환시킬 수는 없습니다.
- 이 역시 생성과 사용은 Observable과 유사합니다. 아래 예제를 봅시다.
func cacheLocally() -> Completable {
return Completable.create { completable in
// Store some data locally
...
...
guard success else {
completable(.error(CacheError.failedCaching))
return Disposables.create {}
}
completable(.completed)
return Disposables.create {}
}
}
- subscribe로 이를 활용할 수 있습니다.
- CompletableEvent는 .completed 혹은 .error만을 제공합니다.
cacheLocally()
.subscribe { completable in
switch completable {
case .completed:
print("Completed with no error")
case .error(let error):
print("Completed with an error: \(error.localizedDescription)")
}
}
.disposed(by: disposeBag)
Maybe
- Single과 Completable이 섞인 버전입니다. .success(value), .completed, .error 모두 방출될 수 있습니다. 프로세스가 성공 실패여부와 더불어 특정 값을 뱉을 수 있을 때 사용합니다.
- asMaybe() 메서드를 통해 아무 Observable을 Maybe로 변환시켜서 확인할 수 있습니다.
- 이 또한 생성과 사용은 Observable과 유사합니다. 아래 예제를 봅시다.
func generateString() -> Maybe<String> {
return Maybe<String>.create { maybe in
maybe(.success("RxSwift"))
// OR
maybe(.completed)
// OR
maybe(.error(error))
return Disposables.create {}
}
}
- subscribe로 이를 활용할 수 있습니다.
generateString()
.subscribe { maybe in
switch maybe {
case .success(let element):
print("Completed with element \(element)")
case .completed:
print("Completed with no element")
case .error(let error):
print("Completed with an error \(error.localizedDescription)")
}
}
.disposed(by: disposeBag)
참고
반응형
'🍎 Apple > Combine & Rx' 카테고리의 다른 글
[RxSwift] Driver, Signal (0) | 2022.02.24 |
---|---|
[RxSwift] ControlProperty, ControlEvent (0) | 2022.02.24 |
[RxSwift] Scheduler (2) | 2022.02.24 |
[RxSwift] Subject (0) | 2022.02.16 |
[RxSwift] Observable & Operator (0) | 2022.02.14 |