RxSwift Ch2
RxSwift 스터디 GitHub 를 보고 하나씩 따라하는 곳입니다
Ch2 Observable
Observable이란?
- 비동기적으로 관찰가능한 이벤트를 방출하는 객체를 말한다
Observable 만들기
just, of, from
let ob1 = Observable.just(1)
let ob2 = Observable.of(1,2,3)
let ob3 = Observable.from([1,2,3])
Observable 구독
위의 옵져버블을 선언하는걸로는 아무일도 일어나지 않습니다.
무조건 구독을 해줘야, 방출하는 값을 받을 수 있음!
subscribe()
let ob1 = Observable.just(1)
ob1.subscribe({ event in
if let element = event.element {
print(element)
}
})
//1
subscribe(onNext: )
let ob2 = Observable.of(1,2,3)
ob2.subscribe(onNext: { (element) in
print(element)
})
/*
1
2
3
*/
.empty()
completed 이벤트를 전달하고 바로 종료
let ob = Observable<Void>.empty()
ob.subscribe(onNext: { (element) in
print(element)
}, onCompleted: {
print("Completed")
})
//Completed
.never()
아무런 이벤트를 전달하지 않음
let ob = Observable<Void>.never()
ob.subscribe(onNext: { (element) in
print(element)
}, onCompleted: {
print("Completed")
})
.range()
let ob = Observable<Int>.range(start: 1, count: 10)
ob.subscribe(onNext: { (element) in
print(element)
})
/*
1
2
3
4
5
6
7
8
9
10
*/
Disposing과 종료
각각의 구독을 관리를 해줘야 하는데, dispose()를 명시적으로 호출하는 방법이 있지만 권장되지 않는다(비효율, 휴먼 에러)
let bag = DisposeBag() 이라는 변수를 하나 선언해서, 모든 구독의 끝에 .disposed(by: disposeBag) 을 호출하면, 모두 bag에 담아놓았다가, 해당 bag이 선언된 부분이 해제될때 한꺼번에 해제시켜준다.
Create
직접 Observable을 customgkrp Create해줄수도 있습니다
let disposeBag = DisposeBag()
let ob = Observable<String>.create { (observer) -> Disposable in
observer.onNext("1")
observer.onNext("4")
observer.onNext("9")
observer.onCompleted()
return Disposables.create()
}
ob.subscribe(onNext: {print($0)},
onError: {print($0)},
onCompleted: {print("Complted")},
onDisposed: {print("Disposed")})
.disposed(by: disposeBag)
Observable factory 만들기
deferred를 이용해서 외부 조건에 영향을 받게 만들 수도 있습니다 :)
import RxSwift
let disposeBag = DisposeBag()
var flip = false
let ob = Observable<Int>.deferred {
flip.toggle()
if flip {
return Observable.of(1,2,3)
} else {
return Observable.of(4,5,6)
}
}
for _ in 0...3 {
ob.subscribe(onNext: {
print($0, terminator: " ")
})
.disposed(by: disposeBag)
print()
}
/*
1 2 3
4 5 6
1 2 3
4 5 6
*/
Traits 사용
보다 좁은 범위의 Observable로써 특정 용도에 적절하다
Single
- success(data) or error 만 방출
- success(data) (는 next + completed를 의미한다)
아래 예제를 보겠습니다
let bag = DisposeBag()
enum NetworkError: Error {
case failToConnect
}
func getRequest(url: String?) -> Single<Bool> {
return Single<Bool>.create { single in
guard let url = url else {
single(.failure(NetworkError.failToConnect))
return Disposables.create()
}
if url == "https://www.apple.com" {
single(.success(true))
} else {
single(.success(false))
}
return Disposables.create()
}
}
getRequest(url: "https://www.apple.com")
.subscribe(onSuccess: { success in
print(success)
},
onFailure: {error in
print(error.localizedDescription)
},
onDisposed: {
print("disposed")
})
.disposed(by: bag)
약간 Result Type 느낌?
Completable
- completed or error 만 방출
enum LoadingError: Error {
case failToLoad
}
let bag = DisposeBag()
func loading(complete: Bool) -> Completable {
return Completable.create { completable in
guard complete else {
completable(.error(LoadingError.failToLoad))
return Disposables.create()
}
completable(.completed)
return Disposables.create()
}
}
loading(complete: true)
.subscribe {
print("completed")
} onError: { error in
print(error.localizedDescription)
}
.disposed(by: bag)
완료했는지 에러가 났는지 여부만 방출합니다. 값은 x
Maybe
- success(data), completed, error를 모두 방출
enum LoadingError: Error {
case failToLoad
}
let bag = DisposeBag()
func study() -> Maybe<String> {
return Maybe<String>.create { maybe in
maybe(.success("RxSwift"))
maybe(.completed)
maybe(.error(LoadingError.failToLoad))
return Disposables.create()
}
}
study()
.subscribe { result in
switch result {
case .success(let language):
print("Study " + language)
case .completed:
print("Completed")
case .error(let error):
print(error.localizedDescription)
}
}
.disposed(by: bag)
이런느낌?
Challenges
do연산자
특정 이벤트가 발생했을때, 실행되는 콜백함수를 등록하고 싶을때 사용.
발생되는 요소를 수정하지 않고 구독자로 그대로 전달합니다
let bag = DisposeBag()
Observable.of(1,2,3,4,5)
.do {
$0 * 10
}
.subscribe(onNext: {
print("sub: ", $0)
})
.disposed(by: bag)
debug연산자
let bag = DisposeBag()
let ob = Observable<Any>.never()
.debug("동작확인")
.subscribe()
.disposed(by: bag)
// 2022-03-25 18:23:34.315: 동작확인 -> subscribed
Author And Source
이 문제에 관하여(RxSwift Ch2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@aurora_97/RxSwift-Ch2저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)