0. Ref
- 곰튀김님 유튜브 내용을 공부하면서 정리하는 내용
- https://www.youtube.com/watch?v=w5Qmie-GbiA&list=PL03rJBlpwTaAh5zfc8KWALc3ADgugJwjq
1. RxSwift
- ReactiveX(http://reactivex.io/languages.html)에서 Swift를 위해 제공되는 것
- Observable, Operators, Scheduler, Subject, Single을 알면 끝난다.
2. 준비
- https://github.com/iamchiwon/RxSwift_In_4_Hours 에서 다운로드 받는다.
- Example > step1 프로젝트를 열어준다.
3. Step1
1) Sync / Async
- onLoadSync는 동기로 메인 쓰레드에서 이미지를 다운로드 받고 이미지를 변경한다.
- onLoadAsync는 비동기로 별도의 Queue에서 이미지를 다운로드 받고 메인 쓰레드에서 이미지를 변경한다.
@IBAction func onLoadSync(_ sender: Any) {
let image = loadImage(from: IMAGE_URL)
imageView.image = image
}
@IBAction func onLoadAsync(_ sender: Any) {
DispatchQueue.global().async {
guard let url = URL(string: self.IMAGE_URL) else { return }
guard let data = try? Data(contentsOf: url) else { return }
let image = UIImage(data: data)
DispatchQueue.main.async {
self.imageView.image = image
}
}
}
2) PromiseKit
- 자바스크립트 등에서 주로 사용되는 방법
- Promise에서 비동기 형태의 함수를 반환
- 함수에서는 seal.fulfill로 데이터를 반환
- callback형태로 호출한 부분에서 done, catch로 처리
@IBAction func onLoadImage(_ sender: Any) {
imageView.image = nil
promiseLoadImage(from: LARGER_IMAGE_URL)
.done { image in
self.imageView.image = image
}.catch { error in
print(error.localizedDescription)
}
}
// MARK: - PromiseKit
func promiseLoadImage(from imageUrl: String) -> Promise<UIImage?> {
return Promise<UIImage?>() { seal in
asyncLoadImage(from: imageUrl) { image in
seal.fulfill(image)
}
}
}
3) Observable
- promiseKit과 비슷한 형태
- seal.onNext로 반환하는 Observable객체를 반환
- 함수를 호출한 부분에서 subscribe로 처리
@IBAction func onLoadImage(_ sender: Any) {
imageView.image = nil
_ = rxswiftLoadImage(from: LARGER_IMAGE_URL)
.observeOn(MainScheduler.instance)
.subscribe({ result in
switch result {
case let .next(image):
self.imageView.image = image
case let .error(err):
print(err.localizedDescription)
case .completed:
break
}
})
}
// MARK: - RxSwift
func rxswiftLoadImage(from imageUrl: String) -> Observable<UIImage?> {
return Observable.create { seal in
asyncLoadImage(from: imageUrl) { image in
seal.onNext(image)
seal.onCompleted()
}
return Disposables.create()
}
}
4) 결론
- RxSwift를 사용하는 이유는 Async한 것을 간결하고 명확하게 사용하기 위해 사용하는 것
// MARK: - IBAction
var disposeBag: DisposeBag = DisposeBag()
@IBAction func onLoadImage(_ sender: Any) {
imageView.image = nil
rxswiftLoadImage(from: LARGER_IMAGE_URL)
.observeOn(MainScheduler.instance)
.subscribe({ result in
switch result {
case let .next(image):
self.imageView.image = image
case let .error(err):
print(err.localizedDescription)
case .completed:
break
}
}).disposed(by: disposeBag)
}
@IBAction func onCancel(_ sender: Any) {
// TODO: cancel image loading
disposeBag = DisposeBag()
}
'앱 개발자 역량 > IOS' 카테고리의 다른 글
RxSwift ] 3. Operator (0) | 2019.07.13 |
---|---|
RxSwift ] 2. Disposable (0) | 2019.07.13 |
ios ]AppStore 배포하기 (0) | 2019.07.09 |
Swift ] 이미지 불러오기 (0) | 2019.06.19 |
[Swift] pull reload 이벤트 (0) | 2019.06.04 |