Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- rxswift
- uitableview
- 리팩토링
- 스위프트
- Refactoring
- uiscrollview
- UICollectionView
- RxCocoa
- 애니메이션
- HIG
- MVVM
- 리펙터링
- Protocol
- Human interface guide
- swift documentation
- swiftUI
- Observable
- SWIFT
- UITextView
- tableView
- Clean Code
- 클린 코드
- 리펙토링
- collectionview
- combine
- Xcode
- ribs
- clean architecture
- ios
- map
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 1. RxSwift의 Map, FlatMap 사용하여 비동기를 순서대로 처리 방법 본문
RxSwift/RxSwift 응용
[iOS - swift] 1. RxSwift의 Map, FlatMap 사용하여 비동기를 순서대로 처리 방법
jake-kim 2022. 1. 31. 02:331. RxSwift의 Map, FlatMap - 사용하여 비동기를 순서대로 처리 방법
2. RxSwift의 Map, FlatMap - 사이드 이펙트 처리 방법 (throw와 catch 사용)
편리를 위해 사용한 프레임워크
# UI
pod 'SnapKit'
pod 'Then'
# Rx
pod 'RxSwift'
pod 'RxCocoa'
# Network
pod 'Moya/RxSwift'
# Utils
pod 'JGProgressHUD' # 로딩
사용한 API - Unsplash
- 이미지 조회를 위한 API
- https://unsplash.com/documentation
비동기 작업 순서
- `확인` 버튼 탭
- API를 통해서 이미지 url 획득, url을 UILabel에 입력
- 로딩 프로그래스 바 표출 후, url을 가지고 이미지를 획득
- 이미지 획득 후 3초 후에 UIImage에 이미지 적용
비동기 작업을 순서대로 처리하는 아이디어
- Rx의 flatMap과 map을 적절히 사용하여 처리
- API 서비스를 Observabe<SomeModel>을 리턴하도록 구현되어 있는 상태라면, 스트림에서 flatMap을 사용하여 데이터 획득
- 위에서 얻어온 데이터를 Map 또는 do(onNext:)에서 처리하고난 후 적절한 값을 다음 스트림에 전달
- 랜덤 이미지 url을 가져오는 API와 url을 가지고 UIImage를 가져오는 API 총 두개를 사용하므로 flatMap도 총 2개 사용 예정
Network
- moya 사용하여 Endpoint 정의
// UnsplashTargetType.swift
import Moya
enum UnsplashTargetType: TargetType {
case getPhoto
}
extension UnsplashTargetType {
var baseURL: URL {
return URL(string: "https://api.unsplash.com/")!
}
var path: String {
switch self {
case .getPhoto:
return "photos/random"
}
}
var method: Method {
switch self {
case .getPhoto:
return .get
}
}
var task: Task {
return .requestPlain
}
var headers: [String : String]? {
return [
"Content-Type": "application/json",
"Authorization": "Client-ID A_zoeYvBtQoSlNw51lkUN0C0YOa3XhvuENeFvI0AIAk"
]
}
}
- 위 Endpoint와 Moya에서 제공하는 provider를 가지고 request하는 컴포넌트 정의
- 단, request한 결과는 Observable 형태로 반환하도록 구현 (Observable를 리턴하면 사용하는 쪽에서 Rx 스트림으로 사용가능하기 때문)
// API.swift
import Moya
import RxSwift
private let provider = MoyaProvider<UnsplashTargetType>()
enum API {
/// 랜덤 이미지 URL 획득
static func getPhoto() -> Observable<Photo> {
provider.rx.request(.getPhoto)
.map(Photo.self)
.asObservable()
.do(onError: { print("Error = \($0)") })
}
/// url을 가지고 UIImage 얻어오는 함수
static func getPhoto(url: String) -> Observable<UIImage> {
guard
let url = URL(string: url),
let data = try? Data(contentsOf: url),
let image = UIImage(data: data)
else { return .empty() }
return .just(image)
}
}
사용하는 쪽
- flatMap과 map을 적절히 사용
- flatMap: Observable을 리턴해야하는 경우 사용하는데, API들은 Observable<MyType>을 리턴하게 되었으므로 사용
- map: 위 flatMap에서 받아온 것중 MyType에 접근하여 특정 값을 처리하고, 다음 스트림에 필요한 값을 리턴해주는데 사용
// ViewController.swift
self.button.rx.tap
.flatMap { API.getPhoto() }
.map(\.urls.regular)
.map { [weak self] in
self?.label.text = $0
return $0
}
.do(onNext: { [weak self] _ in self?.showLoading() })
.flatMap { API.getPhoto(url: $0) }
.delay(.seconds(3), scheduler: MainScheduler.asyncInstance)
.do(onNext: { [weak self] _ in self?.hideLoading() })
.bind(to: self.imageView.rx.image)
.disposed(by: self.disposeBag)
* 전체 코드: https://github.com/JK0369/ExFlatMap
'RxSwift > RxSwift 응용' 카테고리의 다른 글
Comments