1๋
์ rx๋ฅผ ์ฌ์ฉํด์ผ๋ง ํ๋ ํ๋ก์ ํธ๊ฐ ์์ด์ ๊ทธ๋ ์ ๊น ๊ณต๋ถํ๊ณ , ์๋
7์์ฏค ํ๋ฒ ๋ ๊ณต๋ถํ์ง๋ง ๊ทธ๋๋ rx๋ฅผ ์ ์ฌ์ฉํด์ผํ๋์ง, ์ฅ์ ์ ์ฐพ์๋ด๋ ์ดํด๋ ๋์ง๋ง ํฌ๊ฒ ์๋ฟ์ง ์์์ ์กฐ๊ธ ๊ณต๋ถํ๋ค๊ฐ ์์ฐ์ค๋ฝ๊ฒ ์ฌ์ฉํ์ง ์๊ฒ ๋์๋ค.
์ทจ์
์ค๋น๋ฅผ ํ๋ฉด์ ๊ธฐ์กด์ ๋ง๋ค์ด ๋ฐฐํฌํ๋ ๋ค์ด์ด๋ฆฌ ์ฑ ์ฝ๋์ ์ฌ๊ฐ์ฑ์ ๋๊ปด ๋ฆฌํฉํ ๋ง๊ณผ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ๋จ๊ณ์์ ์ฐ์ต์ฉ ํ๋ก์ ํธ๋ก ํ๋๊ฒ ๋ณด๋ค ์ข ๋ ๋ณต์กํ ๋น๋๊ธฐ์ฒ๋ฆฌ๋ฅผ ํด์ผํ ์ผ์ด ์๊ฒผ๋๋ฐ @escaping์ผ๋ก ๋ฒ์ด๋๊ณ ์ค๊ดํธ ์์ผ๋ก ํ๊ณ ํ๊ณ ๋ค์ด๊ฐ๋ ์ฝ๋๋ฅผ ๋ณด๋ ๋ญ๊ฐ ๋ง์์ ๋ค์ง ์์ ์ข ๋ ์ฐพ์๋ณด๋ ์ด๋ฐ ๋ถ๋ถ์ rx๋ก ํด๊ฒฐํ ์ ์๋ค๋ ๊ฒ์ ์๊ฒ ๋์๋ค. ๊ทธ๋๋ถํฐ rx๋ฅผ ๋ฐฐ์์ผ๊ฒ ๋ค๊ณ ์๊ฐํ๊ณ ์ทจ์
์ ํ ํ ํ์ฌ ์ฝ๋๋ฅผ ๋ณด๋ค๋ณด๋ ๋ณต์กํ ๋น๋๊ธฐ ์์๋๋ฌธ์ @escaping์ด ๋ง์์ง๊ณ ๋ณต์กํ ์ฝ๋๋ฅผ ๋ณด๋ rx์ ํ์์ฑ์ ๋๋ผ๊ณ ๋น๋๊ธฐ๋ฅผ ๊ณต๋ถํด๋ณด๊ณ ์ ํ๋ค.
rx๊ฐ ์๋ ์ ๋ช
ํ๊ณ ์ฌ์ฉํ๋ ๊ณณ์ด ๋ง๋ค๋ณด๋ ๋ณต์กํ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํ๋ ค๋ฉด rx๋ฅผ ๋ฐฐ์์ผํ๋ ๊ฒ์ธ๊ฐ๋ผ๋ ์๊ฐ๋ ํ์๋๋ฐ ๊ทธ๋ ์ง๋ ์๋ค.
@escaping์ ์ด์ฉํ ์ฝ๋ฐฑ ํจ์๋ฅผ ํตํด ๋ณต์กํ์ง๋ง ์ฒ๋ฆฌํ ์ ์๊ณ , GCD, Notification Center, Async/Await, PromiseKit, Combine ๋ฑ๋ฑ ๋ค์ํ ๋ฐฉ๋ฒ์ด ์์ง๋ง ์ฝ๋ ๊ฐ๋
์ฑ, ์ฑ๋ฅ ๋ฑ์ ๊ณ ๋ คํ์ฌ ์ ์ ํ ๋ฐฉ๋ฒ์ ์ฐพ๋๊ฒ์ด ์ค์ํ๋ค๊ณ ์๊ฐํ๋ค.
์ ๋ ์ธํ๋ฐ ์จ๋ฐ์ ๋์์ฑํ๋ก๊ทธ๋๋ฐ ๊ฐ์๋ฅผ ๋ฃ๊ณ ๊ธฐ์ด๋ฅผ ๊ณต๋ถํ์๊ณ ,
ํด๋น ํฌ์คํ ์ ์ ๋จธ๋ฆฌ์ ๊ตฌ๊ธ, ๊ณฐํ๊น Rx๊ฐ์๋ฅผ ๋ฃ๊ณ ์ฐธ๊ณ ํ์ฌ ์์ฑํ์์ต๋๋ค.
Rx๋?
![](https://blog.kakaocdn.net/dn/b8NzPy/btsd9Nmpeag/0SHQv39XKy9AU7SkKpQXE1/img.png)
![](https://blog.kakaocdn.net/dn/c5113I/btsegguNZ19/BNKycYwVuq904EBnx5s0R0/img.jpg)
์๋ฌธ ๊ทธ๋๋ก ํด์ํ์๋ฉด ๊ด์ธก๊ฐ๋ฅํ ์คํธ๋ฆผ์ด ์๋ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ์ํ API ์ด๋ค.
๋ญ๊ฐ ๋ง์ด ์น๊ทผํ์ง ์์๋ฐ...
์ด๋ฒคํธ ๋ฐ์์ ๊ด์ฐฐํ๋ ์ฃผ์ฒด(Observable)๊ณผ ์ด๋ฅผ ๊ตฌ๋
ํ๋ ๊ตฌ๋
์(Subscriber) ๊ฐ์ ๊ด๊ณ๋ฅผ ๋งบ์ด ๋ณํ๋ฅผ ๊ฐ์งํ๊ณ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ค.
๊ณ ์ดํดํ๋ค!
Rx ์์
func myFunction(completion: @escaping (String?) -> ()) {
print("Hello")
completion("Hi")
print("world")
}
myFunction() { response in
print(response) // Hi
}
์ฝ๋ฐฑํจ์๋ฅผ ์ด์ฉํ๋ฉด ์์๊ฐ์ด ์์ฑํ ์ ์๋๋ฐ, return์ด ์์ง๋ง myFunctionํจ์๋ฅผ ๋ฒ์ด๋ ๊ฐ์ ์ ๋ฌํ๊ณ ์๋ค. rx๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋น๋๊ธฐ์ ์ผ๋ก ๋ฐ์ํ๋ ๋ฐ์ดํฐ๋ฅผ return์ ํตํด ๊ฐ์ ์ ๋ฌํ ์ ์๋ค.
func myFunction() -> Observable<String?> {
// 1. ๋น๋๊ธฐ๋ก ์๊ธฐ๋ ๋ฐ์ดํฐ๋ฅผ Observable๋ก ๊ฐ์ธ์ ๋ฆฌํดํ๋ ๋ฐฉ๋ฒ
return Observable.create() { response in
DespatchQueue.global().async {
let newData = "newData"
DispatchQueue.main.async {
response.onNext(newData)
response.onComplete() // ํด๋ก์ ์คํ ์ข
๋ฃ => rc ์ฌ๋ผ์ง
}
}
return Disposables.create()
}
}
// 2. Observable๋ก ์ค๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ
myFunction()
.subscribe { event in
switch event {
case let .next(response):
print(response)
case .completed:
break
case .error:
break
}
}
์ ์ฝ๋์ฒ๋ผ return ๊ฐ์ Observable๋ก ๊ฐ์ธ์ฃผ๋ฉด ๋น๋๊ธฐ์ ์ผ๋ก ์์ฑ๋๋ ๋์ค์ ์๊ธฐ๋ ๋ฐ์ดํฐ๋ผ๋๊ฒ์ ์ ์ ์๊ณ , ์๋ subscribe๋ฅผ ํตํด ๋์ค์ ๋ฐ์ดํฐ๊ฐ ์ค๋ฉด ๊ทธ๋ ํธ์ถํ ์ ์๋ค.
switch-case๋ฌธ์์ next๋ ์ฑ๊ณต, error๋ ์คํจ์ด๋ฉฐ next๋ก ์ฑ๊ณตํ๋ฉด complete๋ฅผ ๋ง๋์ผ ์ข
๋ฃ๋๊ณ , error๋ฅผ ๋ง๋๋ฉด complete๋ฅผ ๋ง๋์ง ์์๋ ๋ฐ๋ก ์ข
๋ฃ๋๋ค.
![](https://blog.kakaocdn.net/dn/dmsepb/btsd9MgP4LH/xDYkZrmvke8N1pVRLzqxE1/img.jpg)
ํ์ง๋ง ์ ์ฝ๋์ ๊ฐ์ด ์์ฑํ๋ฉด "Result of call to 'subscribe' is unused"๋ผ๋ ๋
ธ๋ ๊ฒฝ๊ณ ๊ฐ ๋ฐ์ํ๋๋ฐ, ์ด๋ myFunction์ .subscribe()๋ฅผ ์คํํ ํ return ๊ฐ์ ์ฌ์ฉํ์ง ์์๊ธฐ ๋๋ฌธ์ด๋ค.
subscribe()๋ฅผ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ ์ธ๋์ด ์๋ค.
![](https://blog.kakaocdn.net/dn/cCPRyX/btsd4FienO5/gfkKQ4LzdKnKhEjbq0RIp1/img.png)
return๊ฐ์ผ๋ก Disposable์ ๋ฐํํ๊ณ ์๋๋ฐ, ์ด๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
let disposable = myFunction()
.subscribe { event in
switch event {
case let .next(response):
print(response)
case .completed:
break
case .error:
break
}
}
disposable.dispose()
return์ผ๋ก ๋ฐ์ Disposable๋ฅผ ํตํด dispose()๋ฅผ ์คํํ ์ ์๋ค.
dispose()๋ฅผ ์คํํ๋ฉด ์์
์ด ์ทจ์๋๋ค.
subscribe๋ ๋ฆฌํด๊ฐ์ผ๋ก ์ฃผ์ด์ง๋ Disposable๋ฅผ ๊ฐ์ง๊ณ ์๋ค๊ฐ ์ํ๋ ์์ ์ dispose()๋ฅผ ์คํํ์ฌ ์์
์ ์ทจ์ํ ์ ์๋ค.
var disposable: Disposable?
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
disposable?.dispose()
}
func onLoad() {
disposable = .subscribe(onNext: ...
}
์ ์ฝ๋์ ๊ฐ์ด onLoad()๋ฅผ ํตํด ๋ฌด์ธ๊ฐ ๋ค์ด๋ก๋์ ๊ฐ์ ๋์์ ํ๋ ์ค ํ๋ฉด์ด Disappear๋๋ฉด dispose()๋ฅผ ์คํํด ์์
์ ์ค๊ฐ์ ์ทจ์ํ ์ ์๋ค.
์ฌ๋ฌ๊ฐ์ subsribe๊ฐ ์์ ๊ฒฝ์ฐ๋ disposable๋ฅผ ๋ฐฐ์ด๋ก ๋ง๋ค์ด ์ ์ฅํ์ฌ for๋ฌธ์ ํตํด dispose์ํค๋ฉด ๋๋ค.
๊ทธ๋ฌ๋ ์ฌ๋ฌ๊ฐ์ Disposable๋ฅผ DisposeBag๋ก ํ๋ฒ์ ๊ด๋ฆฌํ ์ ์๋ค.
var disposeBag: DisposeBag?
func onLoad() {
disposable = .subscribe(onNext: ...
.disposed(by: disposeBag)
}
์ด์๊ฐ์ด ์์ฑํ๋ฉด ๋ณด๋ค ์ฝ๊ฒ ๊ด๋ฆฌํ ์ ์๊ณ , ๋ฉค๋ฒ๋ณ์์ด๊ธฐ ๋๋ฌธ์ ํด๋์ค๊ฐ ์ฌ๋ผ์ง๋ ํจ๊ป ์ฌ๋ผ์ง๋ค.
func exampleFunc() -> Observable<String?> {
return Observable.create() { emitter in
emitter.onNext("Hello")
emitter.onNext("World")
emitter.onCompleted()
return Disposables.create()
}
1. Observable.create() ์์ฑ
2. ๊ทธ ์์ emitter์ ๊ฐ์ ๊ฐ ํ๋ ๋ง๋ค๊ธฐ
3. onNext๋ฅผ ํตํด ๊ฐ ์ ๋ฌ (์ฌ๋ฌ๊ฐ ๊ฐ๋ฅ)
4. onCompleted()๋ฅผ ํตํด ์ข
๋ฃ
5. Displsables.create()๋ฆฌํด (๋ฉ๋ชจ๋ฆฌ ๋์ ์๋ฐฉ)
6. ์ด๊ฑธ ๋ฆฌํด
* Observable์ ์๋ช ์ฃผ๊ธฐ
1. Create
2. subscribe => Create ํ ๊ตฌ๋ ๋์์๋ ๋์
3. onNext
4. onCompleted / onError
5. Disposed
Operators
![](https://blog.kakaocdn.net/dn/5HmjA/btsepNsrhfx/IhugbtLQSTKE5gOmQknfD0/img.jpg)
func exampleFunc() -> Observable<String?> {
return Observable.create() { emitter in
emitter.onNext("Hello World")
emitter.onCompleted()
return Disposables.create()
}
์ ์์ ์ฝ๋์์๋ Hello World๋ผ๋ String์ ๋๊ธฐ๊ธฐ ์ํด ์ด์๊ฐ์ด ์์ฑํ๋ค.
๊ทธ๋ฌ๋ ํ๋์ ๋ฐ์ดํฐ๋ง์ ์ ๋ฌํ๋๋ฐ ์ฝ๋๊ฐ ๋๋ฌด ๊ธธ๋ค๋ ๋จ์ ์ Operator๋ฅผ ์ฌ์ฉํ์ฌ ๋ณด์ํ ์ ์๋ค.
func exampleFunc() -> Observable<String?> {
return Observable.just("Hello World")
}
์ด์ฒ๋ผ just๋ผ๋ Operator๋ฅผ ์ฌ์ฉํด ์งง๊ฒ ์์ฑํ ์ ์๋ค.
์ฌ๋ฌ๊ฐ์ onNext๋ฅผ ์์ฑํ์ง ์๊ณ Operator๋ฅผ ํตํด ์ฝ๊ฒ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณตํ์ฌ ์ ๋ฌํ ์ ์๋ค.
+) ObserveOn
![](https://blog.kakaocdn.net/dn/Kwt8n/btsep7dj9f3/jFXcoQR3ZGRkuDACLeqia0/img.jpg)
exampleFunc()
.subscribe(onNext: { data in
DispatchQueue.main.async {
self.label.text = data
}
})
exampleFunc()
.ObserveOn(MainScheduler.instance)
.subscribe(onNext: { data in
self.label.text = data
})
observeOn์ ํตํด main์ค๋ ๋์์ ์คํํ๋ ์ฝ๋๋ฅผ ์๋ ์ฝ๋์ ๊ฐ์ด ์ฝ๋ ํ์ค๋ก ์์ฑํ ์ ์๋ค.
'iOS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS] WKWebView ์ฟ ํค ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ (์๋๋ก๊ทธ์ธ) (0) | 2023.06.08 |
---|---|
[iOS] PageViewController ์ฌ์ฉํ๊ธฐ (0) | 2023.05.18 |
[iOS] ๋ทฐ๋ฅผ push, present ํ๋ ๊ณผ์ ์์ ์ด์ navigation controller์ ์ ๊ทผํด ๋ทฐ pushํ๊ธฐ (0) | 2023.04.20 |
[iOS] ์ฝ๋๋ก ํ๋ฉด ๊ตฌ์ฑํ๊ธฐ (0) | 2023.04.20 |
[iOS] xcode Vary for Traits (0) | 2023.03.28 |