Single
์๋ ์ฝ๋๋ observable๋ก ๋ง๋ ๋คํธ์ํฌ ํต์ ์ฝ๋์ด๋ค.
func fetchTestData() -> Observable<TestModel> {
return Observable.create { observer -> Disposable in
AF.request(NetworkManager.testURL)
.validate(statusCode: 200..<300)
.responseDecodable(of: TestModel.self) { response in
switch response.result {
case .success(let success):
observer.onNext(success)
case .failure(let error):
observer.onError(error)
}
}
return Disposables.create()
}
}
๊ทธ๋ฌ๋, ์ ์ฝ๋์๋ ๋ฌธ์ ์ ์ด ํ๋ ์๋ค.
๋ฒํผ์ ํญํ์ ๋, fetchTestData() ๋ฉ์๋๊ฐ ํธ์ถ๋๋ค๊ณ ํ๋ค๋ฉด,
ํด๋น ํธ์ถ๋ถ๋ flatMap์ ํ์ฉํด์ ๋คํธ์ํฌ ์์ฒญ์ ํ์ฌ
ํด๋น ์๋ต๊ฐ์ observable๋ก ๋ณํํ์ฌ subscribe๋ฅผ ํ๊ฒ ๋๋๋ฐ,
๊ตฌ๋
๊ณผ ๋์์ next๋ก ๊ฐ์ด ์ ์ ๋ฌ๋์ง๋ง,
ํ๋ฒ ๋ ํธ์ถํ๋ ค๊ณ ์๋ํ๋ ๊ฒฝ์ฐ!!
์์ subscribe๊ฐ dispose๋์ง ์๊ณ ์คํธ๋ฆผ์ด ์ ์ง๋ ์ํ๋ก
์๋ก์ด ์คํธ๋ฆผ์ ์์ฑ๋๋ค.
(.debug()๋ฅผ ํตํด ํ์ธ!)
๋๋ฒ๊น
์ ์ฐ์ด๋ณด์ง ์์ผ๋ฉด, ์ ์ ์์๋ ๋ฌธ์ ....
๋์ํ๋๋ฐ์๋ ๋ฌธ์ ๋ ์์ง๋ง,
์ด๋๋ก ๊ณ์ ์คํธ๋ฆผ์ด ์์ธ๋ค..? ๋ฉ๋ชจ๋ฆฌ๊ฐ ํด์ ๋์ง ์๋๋ค..?
์ด๊ฒ์ด ๋ฌธ์ .....
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์
๋คํธ์ํฌ ํต์ ์ ์ฑ๊ณตํ์ ๋, ์๋์ ๊ฐ์ด complete๋ฅผ ํด์ฃผ๋ฉด ๋๋ค!
func fetchTestData() -> Observable<TestModel> {
return Observable.create { observer -> Disposable in
AF.request(NetworkManager.testURL)
.validate(statusCode: 200..<300)
.responseDecodable(of: TestModel.self) { response in
switch response.result {
case .success(let success):
observer.onNext(success)
observer.onCompleted() // ์ด๋ ๊ฒ!!
case .failure(let error):
observer.onError(error)
}
}
return Disposables.create()
}
}
complete๋ฅผ ๋ง๋๋ฉด ์คํธ๋ฆผ์ dispose ๋๊ธฐ ๋๋ฌธ์ ์ด ๋ฌธ์ ๊ฐ ๊ฐ๋จํ๊ฒ ํด๊ฒฐ๋๋ค.
๊ทผ๋ฐ, ๋งค๋ฒ ๊ตฌํํ ๋๋ง๋ค complete๋ฅผ ์์ฑํด์ฃผ์ด์ผํ๊ณ ,
dispose๊ฐ ์ ๋๋ก ๋๊ณ ์๋์ง ํ์ธํ๊ธฐ ๋ฒ๊ฑฐ๋กญ๋ค๋ ์ ..!!!!
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ฃผ๋๊ฒ ๋ฐ๋ก Single์ด๋ค!

์ ์ฝ๋๋ Sinlge์ ๊ตฌํ๋ถ ์ฝ๋์ด๋ค.
ํ์ํ ๋ถ๋ถ์ ๋ณด๋ฉด, ์ฑ๊ณต์ ํ ๊ฒฝ์ฐ next ๋ค์์ complete๊ฐ ๊ตฌํ๋์ด ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
(ํ๋ํ๋ complete๋ฅผ ์ฑ๊ฒจ์ฃผ๋ ๊ฒ์ด ๊ท์ฐฎ์๋ ๊ฒ์ Single๋ก ํด๊ฒฐ ๊ฐ๋ฅํ๋ค๋ ๊ฒ!)
์๋ ์ฝ๋๋ Sinlge๋ก ๊ตฌํํ ์ฝ๋์ด๋ค.
func fetchTestDataWithSingle() -> Single<TestModel> {
return Single.create { observer -> Disposable in
AF.request(NetworkManager.testURL)
.validate(statusCode: 200..<300)
.responseDecodable(of: JokeModel.self) { response in
switch response.result {
case .success(let success):
observer(.success(success))
case .failure(let error):
observer(.failure(error))
}
}
return Disposables.create()
}
}
์ด๋ ๊ฒ ๊ตฌํํ๋ฉด ๋ฐฉ์ถ ์ดํ์ ์คํธ๋ฆผ์ด dispose๋๋ค.
๊ทผ๋ฐ,,, ์ฌ๊ธฐ์ ๋ฌธ์ ์ ์ด ํ๋ ๋ ์๋ค!!!๐ก
๋ฐ๋ก error๊ฐ ๋ฐ์ํ์ ๊ฒฝ์ฐ์ด๋ค.
๋ฉ์๋ ํธ์ถํ๋ ํญ observable ๋ด์ ๋คํธ์ํฌ observable์ด ์๋๋ฐ,
ํญ observable์ ์ด์์๊ณ , ๋คํธ์ํฌ๊ฐ error๋ฅผ ๋ณด๋ด๋ฉด ๊ทธ ํญ๋ ์ํฅ์ ๋ฐ๋๋ค.
๊ทธ๋ฐ๋ฐ ์ฐ๋ฆฌ๋ ์์ ์คํธ๋ฆผ์ด error๋ฅผ ๋ฐฉ์ถํ๋๋ผ๋ ๋ถ๋ชจ ์คํธ๋ฆผ์ด error๋ฅผ ๋ฐ์ง ์์
dispose๊ฐ ๋์ง ์๊ณ , ์คํธ๋ฆผ์ด ์ ์ง๋๋๋ก ๊ตฌํํด์ผํ๋ค.
์ด๋ป๊ฒ ํด์ผํ ๊น?๐ค
๋ฐ๋ก
Single<Result>๋ฅผ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค!
์ด ๋ฐฉ๋ฒ์ ํ์ฉํ๋ฉด, error Handling๊ณผ ๋์์ ์คํธ๋ฆผ์ ์ ์งํ ์ ์๋ค.

๋ด๋ถ ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด,
success์ failure ๋ ๊ฐ์ง ์ผ์ด์ค๊ฐ ์๋ค.
Result ํ์
์ผ๋ก ๊ตฌํํ ๊ฒฝ์ฐ
Sinlge์์ subscribe๊ฐ ๋๊ธฐ์ง ์๋๋ก!
์คํจ ์, success๋ฅผ ๋ฐฉ์ถํ๊ณ ๊ทธ ์์ ๋ช
์ํด ๋์ Error๋ฅผ ๋ด์์ ๋ฐฉ์ถํ๋ ๊ฒ.
enum APIError: Error {
case invalidURL
case unknownResponse
case statusError
}
์ด๋ ๊ฒ Error ํ์
์ APIError Enum์ ๋ง๋ค๊ณ ,
func fetchTestDataWithSingleResultType() -> Single<Result<TestModel, APIError>> {
return Single.create { single -> Disposable in
AF.request(NetworkManager.testURL)
.validate(statusCode: 200..<300)
.responseDecodable(of: TestModel.self) { response in
switch response.result {
case .success(let success):
single(.success(.success(success)))
case .failure(_):
single(.success(.failure(.invalidURL)))
}
}
return Disposables.create()
}
}
์ด๋ ๊ฒ failure์ ๊ฒฝ์ฐ์๋ Sinlge๋ก ๋ํํ์ฌ success๋ก ํด๋น Error๋ฅผ ๋ด์์ ๋ณด๋ด๋ฉด ๋๋ค.
failure์์
let statusCode = response.response?.statusCode
switch statusCode {
case 400:
observer(.success(.failure(.missingRequiredValue)))
case 402:
observer(.success(.failure(.noSpacesAllowed)))
case 409:
observer(.success(.failure(.alreadySignedUp)))
default:
break
}
์ด๋ ๊ฒ ํ์ํ statusCode๋ฅผ Switch๋ฌธ์ ํตํด ๋ฐฉ์ถํ ์๋ ์๋ค.
Result ํ์
์ผ๋ก ํธ๋ค๋งํ๋ ๋ฐฉ๋ฒ ์ด์ธ์๋ flatMap ๋ด๋ถ์์ catch๋ฌธ์ ํตํด ์ฒ๋ฆฌ๋ ๊ฐ๋ฅํ๋ค.
(์ด ๋ฐฉ๋ฒ์ ์ถํ์ ์ด์ด์ ์ ๋ฆฌํ ์์ ์ด๋ค.)
'RxSwift' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[RxSwift] BehaviorSubject, PublishSubject, ReplaySubject, AsyncSubject (0) | 2024.06.26 |
---|---|
[RxSwift] Observable & Observer (just, of, from, create) (0) | 2024.06.24 |