곰튀김 님의 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... 이란? - 항상 정확한 의미를 모르는 채로 사용해 왔는데 다음 스터디에서 이걸 정리해 주시는 분이 계셔서 신난다!