[RxSwift] 이게 맞나? 싶은 RxSwift 개념 정리
iOS/Swift

[RxSwift] 이게 맞나? 싶은 RxSwift 개념 정리

곰튀김 님의 RxSwift 4시간에 끝내기 (종합편) 영상을 보고 작성한 글입니다 ^~^

https://youtu.be/w5Qmie-GbiA

 

정말 생초보,, 아무것도 모르는 입장에서 강의 영상을 보고 의식의 흐름대로 작성한 글이니 비판의 눈으로 글을 읽어 주시면 감사하겠습니다~~ 오류 지적 대환영!

 

[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를 onNextonCompleted 순서로 실행시킴.

 

onNextswitch-case 문의 .next로 빠져 구문을 실행하고, 완료되면 다음 작업인 onCompleted.completed로 빠져 구문을 실행함.

 

 

👣 Subscribe

  • 나중에 오는 데이터 받으려고 대기
  • .subscriberesult의 경우의 수는 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... 이란? - 항상 정확한 의미를 모르는 채로 사용해 왔는데 다음 스터디에서 이걸 정리해 주시는 분이 계셔서 신난다!