応答式プログラミング総合演習

6710 ワード

紹介する
この文章は応答式のプログラミングを学びたい初心者だけに差し上げます.このデモは完全な登録機能の実現であり、第三者を含む:
  • RxSwift
  • RxCocoa
  • Moya
  • SwiftJson
  • Object Mapper
  • Alamoffireは登録ページの入力チェック、http設定と要求、モデル変換、キャッシュ、カスタムエラー処理プラグイン
  • を実現しました.デモの構造紹介
  • DMUser:ユーザモデル
  • DM Login View Controller:ログインコントローラ
  • DM Loging Resoult:ログイン状態(列挙)
  • DM Logiview Model:データ業務処理
  • DMLogiProtocols:登録するためのインターフェース(プロトコル)
  • DM LoginnService:サービス(特定のクラスで定義されたプロトコルインターフェースを実現しました)
  • DM LogingHttp:MoyaのTarget Typeに従い、定義を要求する
  • DDeployProvider:要求の追加構成を提供し、requestとsession manager
  • を含む.
  • DMMoyaHttpErrowr HandlePlugin:カスタムプラグインは、エラーを一括処理するために使用できます.
  • DMCache:キャッシュし、RxMoyaサポートキャッシュ
  • を拡張する.
    データ検証
    登録された入力チェックについては、RXSwift公式demo内のGighubSignupのUsingDriver>2を直接使用して、このチャプタをスキップすることができます.
         driver,
      driver observable   ,       :
    * Can't error out (        )
    * Observe on main scheduler (      )
    * Subscribe on main scheduler (      )
    * Sharing side effects (     ,shareReplay())
    
          UsingDriver > 2  UsingVanillaObservables > 1     
    
    公式の例を紹介します.
    公式の例はMVM+OOPのスキームで実施される.コントローラでは、入力元(テキストボックス、ボタンなどのイベント)と、プロトコルを実装するサービスクラスのインスタンスをview modelに伝え、入力元の変化をviemodelで観察して処理し、コントローラでこれらの信号(処理された信号)を購読します.流れは大体このようです.具体的な参考コードはここで重点的に二つを紹介します.
    データの転送については、データの流れとも言える.
    swiftクローズドの特性のため、クローズドパラメータは声明パラメータのタイプを表示していないか、または直接パラメータリストを省略しています.$0、$1の代わりに、理解上の不便をもたらしています.
    //viewmodel      
    validateUserName = input.userName.flatMapLatest {
                return validService.validationUserName($0)
                  .asDriver(onErrorJustReturn: .failed(message: "      "))
     }
    //      
    func validationUserName(_ usernName: String) -> Observable
    //        
    func checkUserNameAvaliable(userName: String) -> Observable
    //     UI  
    viewModel.validateUserName
              .drive(userNameValidLabel.rx.validationResult)
              .addDisposableTo(disposeBag)
    
    この流れの中で、データはどのように伝えられて使われていますか?
    初心者が接触し始めたばかりなので、戸惑いがあるかもしれません.この点は関数式プログラミングのいくつかの概念(Functor、Applicative、Monad)に言及したいです.興味があれば読んでみてください.理解に役立ちます. : a A, B, C, , , :雷純鋒の技術ブログ1雷純鋒の技術ブログ2
    上のコードセグメントを解析:
  • view modelでテキストボックスの変化を観察します.flatMapLatestは最新の捨てる古いパラメータを取得します.このクローズド内で省略されているパラメータはテキストボックスのテキストです.すなわちtext Field.text(=>0はテキストを検査方法に伝えます.
  • は、検証方法において、テキストに対する検証を完了し、観察可能なオブジェクトに戻り、Observableは、Validation Resultをカプセル化したものである(一般的な値が上下文の値に変わり、チェーン呼び出しが便利であるということが理解できる)、この方法で検証要求を呼び出す方法である.
  • は、検証要求の方法において、実際にネットワーク要求を開始し、ネットワーク要求結果を処理し、Observableのような値を返し(一般的なbookタイプの値をコンテキストの値としてカプセル化すると理解できる)、検査方法においてObservableをObservableに変換する.
  • はview modelに戻ります.validService.validationUserName()この方法は前のステップの処理結果Observableを取得します.driverは特殊なobservableです.条件を満たせばdriverに変換できますが、observableはエラー終了信号が発生します.driverは正常に伝送できません.
  • 制御装置において、view Model.validateUser Name.driveは、前の処理結果Observableを取得しました.次に、どのように結果をUIに具体的に結び付けますか?
  • 処理結果とUIの結合
    extension Reactive where Base: UILabel {
    
        var validationResult: UIBindingObserver {
            return UIBindingObserver(UIElement: base) { label, result in
                label.textColor = result.textColor
                label.text = result.description
            }
        }
    }
    
    RxCocoaがサポートしているものはそのまま使用できますが、サポートされていないもの、またはカスタムが必要なものはこの方法を実現するために、ここでReactiveを拡張し、Validation Resultに対するlabelのカスタムディスプレイを実現します.
    ネットワーク要求
    ネットワーク要求はAlamoffireよりも一段上の抽象を採用しており、MoyaもRxSwiftをサポートしている.基本的な使い方は多く紹介されていませんが、demo(DLoginHttp,DMC LoginnService)や他のブログを参照して、他のユーザー定義を紹介します.まずその初期化パラメータを紹介します.標準値があります.省略できますが、業務はいつも複雑で変化が多いです.私達の注文が必要です.だから、まずその各パラメータの意味を理解して配置します.公式文書Providers.mdが表示されます.
    public init(
    endpointClosure: @escaping (Target) -> Moya.Endpoint = default, 
    requestClosure: @escaping (Moya.Endpoint, @escaping Moya.MoyaProvider.RequestResultClosure) -> Swift.Void = default,
    stubClosure: @escaping (Target) -> Moya.StubBehavior = default, 
    manager: Moya.Manager = default,
    plugins: [PluginType] = default,
    trackInflights: Bool = default)
    
  • Moyaの方式は、endPoint->requestであるので、ここでは要求を再設定し、url、headerなどを含む.
  • 受信前のendPointはrequestの例を生成し、ここでrequestを再設定することができる.
  • は、アナログ要求を制御するために使用され、すなわち、リターンはローカルデータである.
  • は、Alamoffireのsession Managerの例を生成するために使用され、ここでタイムアウト時間、httpsの自己署名証明書の設定などを行うことができます.もし以前にAlamoffを使用したmanagerの設定をここに移植することができます.
  • プラグインの設定は、自身が3つのプラグイン(Network ActivityPlugin、CredntialsPlugin、Network Loggarger Plugin)を提供しており、プラグインをカスタマイズして実現することもでき、プラグインプロトコル
  • を実現するだけでよい.
  • trockInflights?(ちょっと分かりませんが、知っていることがあります.教えてください.)
  • このデモについてカスタムしました.
  • DDeployProvider:endPointとmanager
  • を定義しました.
  • DMoyaHttpErrowr HandlePlugin:カスタムプラグイン、エラー統一処理
  • キャッシュ
    Moyaはオフラインキャッシュを提供していないので、自分でMoyaを拡張してキャッシュを実現する必要があります.この例では、キャッシュは辞書としてメモリに存在していますが、これは実際のキャッシュフレームに置き換えられます.ここでは、キャッシュをどのように拡張するかを示すためだけです.
    DMCache.swiftではキャッシュポリシーを定義しました.DMCacheTypeキャッシュ類(偽、モデル用):DMCache拡張:Moyaサポートキャッシュ、tryCache()
        :
    return Observable.create({[weak self, weak cache]  observe -> Disposable in
                
                switch cacheType {
                case .onlyCache:
                    print("    !!!")
                    if let response = cache?.getValue(forKey: identifier) {
                        observe.onNext(response)
                    }
                    observe.onCompleted()
                case .cacheThenRequest:
                    print("          !!!")
                    if let response = cache?.getValue(forKey: identifier) {
                        observe.onNext(response)
                    }
                    fallthrough
                case .onlyRequest:
                    print("    !!!")
                    task = self?.request(target) { result in
                        switch result {
                        case let .success(response):
                            observe.onNext(response)
                            observe.onCompleted()
                            cache?.storeValue(response, forKey: identifier)
                        case let .failure(error):
                            observe.onError(error)
                        }
                    }
                }
                return Disposables.create {
                    task?.cancel()
                }
            })
    
    
    ここでは、異なるキャッシュポリシーに基づいて、包装を実現するだけでよい.fallthroughキーワードに注意して、穴に注意してください.
    モデル
    最後にデータを持って、Object Mapperを使ってJSONモデルを回転すればいいです.多く紹介してくれません.
    まとめ:このdemoは応答式プログラミングで多くの機能を結合する方法を示しています.RxSwiftとMoyaの結合使用を重点的に紹介しました.後はRxSwiftの実現原理と全方位に注目して説明します.
     ~      ~       ~