Today 12/24
여태까지의 정상적인 사용방법
func downloadJson(_ url: String) -> Observable<String?> {
return Observable.create { emitter in
emitter.onNext("Hello World")
emitter.onCompleted()
return Disposables.create()
}
}
데이터 단지 하나를 보내려는데 너무 서술할 코드들이 많다. → Sugar API
func downloadJson(_ url: String) -> Observable<String?> {
Observable.just("Hello World")
}
func downloadJson(_ url: String) -> Observable<[String?]> {
Observable.just(["Hello","World"])
}
func downloadJson(_ url: String) -> Observable<String?> {
Observable.from(["Hello","World"])
}
데이터를 생성할 때 사용하는 Sugar
just
를 통해 하나의 데이터, 혹은 배열을 전달할 수 있고, from
을 사용하면 배열 형식으로 쓰더라도 배열에 있는 데이터가 하나씩 하나씩 전달된다.
@IBAction func onLoad() {
editView.text = ""
setVisibleWithAnimation(activityIndicator, true)
_ = downloadJson(MEMBER_LIST_URL)
.subscribe { event in
switch event {
case .next(let t):
print(t)
case .completed:
break
case .error:
break
}
}
}
.subscribe
또한 마찬가지이다.
@IBAction func onLoad() {
editView.text = ""
setVisibleWithAnimation(activityIndicator, true)
_ = downloadJson(MEMBER_LIST_URL)
.subscribe(onNext: { print($0) }, onCompleted: { print("Complete")})
}
Operator
데이터를 전달하는 과정에서 중간에 데이터 처리를 해주는 역할을 한다.
@IBAction func onLoad() {
editView.text = ""
setVisibleWithAnimation(activityIndicator, true)
_ = downloadJson(MEMBER_LIST_URL)
.subscribe(onNext: { json in
DispatchQueue.main.async {
self.editView.text = json
self.setVisibleWithAnimation(self.activityIndicator, false)
}
})
}
항상 처리해주기 귀찮았던 DispatchQueue.main.async
또한 operator을 사용하여 간단히 처리가 가능하다.
@IBAction func onLoad() {
editView.text = ""
setVisibleWithAnimation(activityIndicator, true)
_ = downloadJson(MEMBER_LIST_URL)
**.observeOn(MainScheduler.instance)**
.subscribe(onNext: { json in
self.editView.text = json
self.setVisibleWithAnimation(self.activityIndicator, false)
})
}
operators의 종류들과 사용법에 대하여 살펴볼 수 있다.
@IBAction func onLoad() {
editView.text = ""
setVisibleWithAnimation(activityIndicator, true)
_ = **downloadJson**(MEMBER_LIST_URL)
.map {String($0?.count ?? 0 )}
.**subscribeOn**(ConcurrentDispatchQueueScheduler(qos: .default))
.observeOn(MainScheduler.instance)
.subscribe(onNext: { json in
self.editView.text = json
self.setVisibleWithAnimation(self.activityIndicator, false)
})
}
.subscribeOn
은 서술된 위치와 상관없이 downloadJson이 어떤 쓰레드에서 작업하게 할지 결정한다. (그 뒤에 .observeOn이 나오지않으면 계속 유지) - upStream
.observeOn
은 서술된 위치 다음부터 지정된 쓰레드에서 작업될 수 있게 한다. - downStream
.zip
쌍을 만들어서 내보내준다. 마지막에 남는 것이 있으면 내려보낼 수 없다.
.combineLatest
.zip과 같은데 항상 그 전 것과 쌍을 만들어서 내보내준다.
DisposeBag
var disposable: [Disposable] = []
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
disposable?.forEach {$0.dispose() }
}
@IBAction func onLoad() {
editView.text = ""
setVisibleWithAnimation(activityIndicator, true)
let jsonObservable = downloadJson(MEMBER_LIST_URL)
let helloObservable = Observable.just("Hello World")
let d = **Observable.zip**(jsonObservable, helloObservable) {$1 + "\n" + $0!}
.observeOn(MainScheduler.instance)
.subscribe(onNext: { json in
self.editView.text = json
self.setVisibleWithAnimation(self.activityIndicator, false)
})
disposable.append(d)
}
.dispose()를 시켜주지 않으면 view가 사라졌을 때도 계속 동작이 작동한다. 그러므로 처리를 해줘야 한다.
Observable이 많을 경우 Disposable
을 배열로 만들고 view가 끝나는 시점에 모든 disposable을 dispose()시킬 수 있다. 하지만 매번 이렇게 처리하는 것이 귀찮으니 SugarAPI를 사용한다.
var disposeBag = DisposeBag()
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
disposable?.forEach {$0.dispose() }
}
@IBAction func onLoad() {
editView.text = ""
setVisibleWithAnimation(activityIndicator, true)
let jsonObservable = downloadJson(MEMBER_LIST_URL)
let helloObservable = Observable.just("Hello World")
**Observable.zip**(jsonObservable, helloObservable) {$1 + "\n" + $0!}
.observeOn(MainScheduler.instance)
.subscribe(onNext: { json in
self.editView.text = json
self.setVisibleWithAnimation(self.activityIndicator, false)
})
.disposed(by: disposeBag)
}
Dispose를 받는 가방인 DisposeBag()
을 만들어주자.
let d로 받아서 d를 넣는 것도 귀찮다! → .disposed(by: disposeBag)