RxSwift終了4時間-観測不可


Today 12/22
Observable
ReactiveX-マイクロソフトで初めて作成されました.適用方法が似ているので、RxSWIFTが分かれば他の言語でも簡単に適用できます.
DispatchQueueとEscapping HandlerによるSwift内の非同期駆動方式は概ねそうである.
func downloadJson(listUrl: String, downloadJsonHandler: @escaping (String?) -> ()) {
        DispatchQueue.global().async {
            let url = URL(string: listUrl)!
            let data = try! Data(contentsOf: url)
            let json = String(data: data, encoding: .utf8)
            DispatchQueue.main.async {
                downloadJsonHandler(json)
            }
        }
    }

@IBAction func onLoad() {
        editView.text = ""
        setVisibleWithAnimation(activityIndicator, true)
        downloadJson(listUrl: MEMBER_LIST_URL) { json in
            self.editView.text = json
            self.setVisibleWithAnimation(self.activityIndicator, false)
        }
    }
しかしながら、このように実現すると、重複するコードと持続的なインデントは、コードの毒性を低下させる.
だからRxのコアはこのようにdownloadJsonHandler: @escaping (String?) -> ()を受け入れることができませんか?
func downloadJson(listUrl: String) -> Observable<String?> {
				// 1. 비동기로 생기는 데이터를 Observable로 감싸서 리턴하는 방법
        return Observable.create() { f in
            DispatchQueue.global().async {
                let url = URL(string: listUrl)!
                let data = try! Data(contentsOf: url)
                let json = String(data: data, encoding: .utf8)
                DispatchQueue.main.async {
                    f.onNext(json)
										**f.onCompleted()**
                }
            }
            return Disposables.create()
        }
    }

@IBAction func onLoad() {
        editView.text = ""
        setVisibleWithAnimation(activityIndicator, true)
        
				// 2. Observable로 오는 데이터를 받아서 처리하는 방법
        downloadJson(listUrl: MEMBER_LIST_URL)
            .subscribe { event in
                switch event {
                case let .next(json):
                    self.editView.text = json
                    self.setVisibleWithAnimation(self.activityIndicator, false)
                case .completed:
                    break
                case .error:
                    break
                }
            }
    }
String?return Disposables.create()で作業をキャンセルすることもできます..dispose()を加えたのは,ループ参照の問題を解決するためである.f.onCompleted()は一度だけ呼ばれる必要はありません.複数のデータを複数回ロードして渡すことができます.
URLセッションの使用方法
func downloadJson(_ url: String) -> Observable<String?> {
        return Observable.create() { emitter in
            let url = URL(string: url)!
            let task = URLSession.shared.dataTask(with: url) { (data, _, err) in
                guard err == nil else {
                    emitter.onError(err!)
                    return
                }
                if let dat = data, let json = String(data: dat, encoding: .utf8) {
                    emitter.onNext(json)
                }
                emitter.onCompleted()
            }
            task.resume()
            return Disposables.create() {
                task.cancel()
            }
        }
    }

@IBAction func onLoad() {
        editView.text = ""
        setVisibleWithAnimation(activityIndicator, true)
        
        downloadJson(MEMBER_LIST_URL)
						.debug()
            .subscribe { event in
                switch event {
                case let .next(json):
										DispatchQueue.main.async {
                        self.editView.text = json
                        self.setVisibleWithAnimation(self.activityIndicator, false)
                    }
                case .completed:
                    break
                case .error:
                    break
                }
            }
    }
ライフサイクルの観測
  • Create
  • Subscribe
  • onNext
  • onCompleted/onError
  • Disposed
  • f.onNext()はこのように創造されました購読しないと、ライフサイクルは実行されません.let ob = downloadJson()を用いてlogでライフサイクルを観察することができる.