๊ณฐํ๊น ๋์ RxSwift 4์๊ฐ์ ๋๋ด๊ธฐ (์ข ํฉํธ) ์์์ ๋ณด๊ณ ์์ฑํ ๊ธ์ ๋๋ค ^~^
์ ๋ง ์์ด๋ณด,, ์๋ฌด๊ฒ๋ ๋ชจ๋ฅด๋ ์ ์ฅ์์ ๊ฐ์ ์์์ ๋ณด๊ณ ์์์ ํ๋ฆ๋๋ก ์์ฑํ ๊ธ์ด๋ ๋นํ์ ๋์ผ๋ก ๊ธ์ ์ฝ์ด ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค~~ ์ค๋ฅ ์ง์ ๋ํ์!
[1๊ต์] ๊ฐ๋ ์ก๊ธฐ - RxSwift๋ฅผ ์ฌ์ฉํ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ
โ๏ธ Rx์ ๋ชฉ์
๋น๋๊ธฐ์ ์ผ๋ก ๋ง๋ค์ด์ง๋ ๋ฐ์ดํฐ(์ธ์ ๋ง๋ค์ด์ง์ง ๋ชจ๋ฆ)๋ฅผ
completion
์ผ๋ก ์ ๋ฌํ๋ ๊ฒ ์๋๋ผ ๋ฆฌํด ๊ฐ์ผ๋ก ์ ๋ฌํ์ฌ ์ข ๋ ๊ฐ๊ฒฐํ๊ฒ ์ฌ์ฉํ๋๋ก ๋ง๋ค์ด์ง ์ ํธ๋ฆฌํฐ
- ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ์์ ๋์ค ์ทจ์ ์ ์ ์ฉ
- ๋๊ธฐ/๋น๋๊ธฐ ์ฒ๋ฆฌ ์ฝ๊ณ ๊ฐ๋จํ๊ฒ
create, subscribe, disposable
// MARK: RxSwift ์ํ ์ฌ์ฉ
func showImageRx(_ url: String) -> Observable<UIImage?>{
return Observable.create { seal in
asyncLoadImage(from: url) { image in
**seal.onNext(image) // 2
seal.onCompleted() // 4**
}
return Disposables.create()
}
}
@IBAction func tapDownloadRxBtn(_ sender: Any) {
disposable = showImageRx(imageURLStr)
.observe(on: MainScheduler.instance) // 1 5
**.subscribe**({ result in
switch result {
case let .next(image): // 3
print("called .next")
self.imageView.image = image
case let .error(err):
print(err.localizedDescription)
case .completed: // 6
print("called .completed")
break
}
})
}
@IBAction func tapDisposeBtn(_ sender: Any) {
disposable?.dispose()
}
์๋ฐ ํจ์๋ฅผ ๋ง๋ค์ด์ tapDownloadRxBtn
์ ์คํ์์ผฐ์ ๋! ๋ก๊ทธ์ ์ด๋ ๊ฒ ์ฐํ๋ ๊ฑธ ๋ณผ ์ ์์

์ ์๊ฐ์.. ์ฃผ์ ๋ฌ์ ๋์ ์์๋๋ก ์ฒ๋ฆฌ๋๋ ๊ฒ ๊ฐ์ด๋ค..
Main ์ค๋ ๋์์ ๋์๊ฐ๋(UI ์์
์ ์ฒ๋ฆฌํด์ผ ํ๊ธฐ ๋๋ฌธ), Observable
๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ showImageRx()
๋ฅผ ๋ง๋ค์ด ๋๊ณ , asyncLoadImage()
๋ฅผ ํตํด ๋ง๋ค์ด์ง image๋ฅผ onNext
โ onCompleted
์์๋ก ์คํ์ํด.
onNext
โ switch-case
๋ฌธ์ .next
๋ก ๋น ์ ธ ๊ตฌ๋ฌธ์ ์คํํ๊ณ , ์๋ฃ๋๋ฉด ๋ค์ ์์
์ธ onCompleted
โ .completed
๋ก ๋น ์ ธ ๊ตฌ๋ฌธ์ ์คํํจ.
๐ฃ Subscribe
- ๋์ค์ ์ค๋ ๋ฐ์ดํฐ ๋ฐ์ผ๋ ค๊ณ ๋๊ธฐ
.subscribe
์result
์ ๊ฒฝ์ฐ์ ์๋switch-case
๋ฌธ์ฒ๋ผ ์์ผ๋ฉฐ, ๋ค๋ฅธ ๊ฒฝ์ฐ๋ฅผ ์ถ๊ฐํ ์๋ ์๊ฒ ์. ์ด๋ค์ ๊ตฌ๋ ๊ณผ์๋ฆผ์ค์ ์ฒ๋ผ...result
๋ก ๋ค์ด์ค๋ ์น๊ตฌ๋ค์ ๋ํด ์์ ์ ์ํํ๋ ค๊ณ ํญ์ ๊ตฌ๋ ON ์ํ์ธ ๊ฒ ์๋๊น...??????
๐ Dispose โ ์ทจ์
// ์ ์ธ
var disposable: Disposable?
// dispose
disposable?.dispose()
- DisposeBag(๊ฐ๋ฐฉ): Dispose๋ค์ ๋ด๋ ๊ณณ, ์ฌ๋ฌ๊ฐ์ Dispose๋ค์ ๋ด์์ ํ๋ฒ์ ์ฒ๋ฆฌ ๊ฐ๋ฅ
// ์ ์ธ
var disposeBag = DisposeBag()
// dispose
Observable.just("Hello World")
.subscribe(onNext: { str in
print(str)
})
**.disposed(by: disposeBag)**
// ๋ชจ๋ Observable ์ด๊ธฐํ
disposeBag = DisposeBag()
- Dispose๋ฅผ ํด์ผ ํ๋ ์ด์ - ์ผ๊ณฐ๋ท๋ท ๊ฒ์๊ธ์์ ๋ฐ์ท

๐ Observable ๋ค์ํ๊ฒ ์ฌ์ฉํ๊ธฐ
์ ์๋ฅผ ๋ญ๋ผ๊ณ ๋ด๋ฆฌ๋ฉด ์ข์๊น...
Observable.just("800x600")
.map { $0.replacingOccurrences(of: "x", with: "/") }
.map { "https://picsum.photos/\($0)/?random" }
.map { URL(string: $0) }
.filter { $0 != nil }
.map { $0! }
.map { try Data(contentsOf: $0) }
.map { UIImage(data: $0) }
.subscribe(onNext: { image in
self.imageView.image = image
})
.disposed(by: disposeBag)
.just (์์ฑ)
- ๋ฐ์ดํฐ ํ๋๋ง ๋ฐ์?!?
.from (์์ฑ)
- ๋ฐฐ์ด๋ง ๋ฐ์! ๋ฐฐ์ด์ด ์์์๋ถํฐ ํ๋์ฉ ๋ค์ด๊ฐ (์์ ๋ฐ์ดํฐํ์ ์๊ด ใดใด)
.from(["RxSwift", "In", 4, "Hours"])
.map (๋ณํ)
- ๋ฌด์ธ๊ฐ ๋ฐ์ ๊ฐ์ด ์์ ๋! ๊ฑ๋ฅผ
{ ์ด๋ป๊ฒ ์ฒ๋ฆฌํจ }
.map { str in "\(str) RxSwift" }
- from ๋ฑ ์์ฑํ๋ ์น๊ตฌ๋ค๊ณผ ๊ฐ์ด ์ธ ์ ์์!
- ์ด๋ ๊ฒ ์ค ์ธ์์
from
๊ฑฐ์ณค๋ค๊ฐmap
๊ฑฐ์ณค๋ค๊ฐsubscribe
๊น์ง... ์ฃผ๋ฅด๋ฅต ์ด์ด์ง๋ ๊ฒ์ Stream์ด๋ผ๊ณ ํจ! - Observable์ ๋์ด๋ค(Stream)์ผ๋ก ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ ํ๋ ๊ฒ์ด Rx..~~!
- ์ด๋ ๊ฒ ์ค ์ธ์์
Observable.from(["with", "๊ณฐํ๊น"]) .map { $0.count } .subscribe(onNext: { str in print(str) }) // 4 3
.filter (ํํฐ)
if
๋ฌธ์ฒ๋ผtrue
์ผ ๋๋ง ๋ฐ์ผ๋ก ๋ด๋ ค๊ฐ๋๋ก(ํต๊ณผํ๋๋ก) ์ฌ์ฉ!
โ ์ถ๊ฐ๋ก ์ ๋ฆฌํ๋ฉด ์ข์ ๋ด์ฉ(๊ฐ๊ฐ๊ฐ๊ฐ๊ฐ๊ฐ๊ฐ๊ฐใ ์ธ์ )
$0, $1... ์ด๋? - ํญ์ ์ ํํ ์๋ฏธ๋ฅผ ๋ชจ๋ฅด๋ ์ฑ๋ก ์ฌ์ฉํด ์๋๋ฐ ๋ค์ ์คํฐ๋์์ ์ด๊ฑธ ์ ๋ฆฌํด ์ฃผ์๋ ๋ถ์ด ๊ณ์ ์ ์ ๋๋ค!