RxSwift Ch2


RxSwift学習GitHubを見て、次から次へと続く場所.

Ch2 Observable


観測可能なものは何ですか。

  • とは、非同期観察可能なイベントを解放するオブジェクト
  • を意味する.

    Observableの作成


    just, of, from
    let ob1 = Observable.just(1)
    let ob2 = Observable.of(1,2,3)
    let ob3 = Observable.from([1,2,3])

    観測可能購読


    上の擎天柱は何も起こらないと宣言した.
    必ず購読しなければ、配布価格を受け取ることができません!

    subscribe()

    let ob1 = Observable.just(1)
    
    ob1.subscribe({ event in
        if let element = event.element {
            print(element)
        }
    })
    
    //1

    subscribe(onNext: )

    let ob2 = Observable.of(1,2,3)
    
    ob2.subscribe(onNext: { (element) in
        print(element)
    })
    
    /*
    1
    2
    3
    */

    .empty()


    完了したイベントを転送し、すぐに終了します.
    let ob = Observable<Void>.empty()
    
    ob.subscribe(onNext: { (element) in
        print(element)
    }, onCompleted: {
        print("Completed")
    })
    
    //Completed

    .never()


    イベントを転送しない
    let ob = Observable<Void>.never()
    
    ob.subscribe(onNext: { (element) in
        print(element)
    }, onCompleted: {
        print("Completed")
    })

    .range()

    let ob = Observable<Int>.range(start: 1, count: 10)
    
    ob.subscribe(onNext: { (element) in
        print(element)
    })
    
    /*
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    */

    表示と終了


    各サブスクリプションを管理する必要がありますが、dispose()を明示的に呼び出す方法がありますが、この操作は推奨されません(無効、人為的なエラー)
    let bag=DisposeBag()は、すべてのサブスクリプションの最後に変数を宣言します.deposed(by:deposseBag)を呼び出し、すべてのコンテンツをパッケージに入れ、そのパッケージが宣言された部分が解除されると、一度に解除されます.

    Create


    Observableを直接作成することもできます
    let disposeBag = DisposeBag()
    
    let ob = Observable<String>.create { (observer) -> Disposable in
        observer.onNext("1")
        observer.onNext("4")
        observer.onNext("9")
        
        observer.onCompleted()
        
        return Disposables.create()
    }
    
    ob.subscribe(onNext: {print($0)},
                 onError: {print($0)},
                 onCompleted: {print("Complted")},
                 onDisposed: {print("Disposed")})
    .disposed(by: disposeBag)

    観測可能な工場の作成


    また、deferredを使用して外部条件に影響を与えることもできます:)
    import RxSwift
    
    let disposeBag = DisposeBag()
    
    var flip = false
    
    let ob = Observable<Int>.deferred {
        flip.toggle()
        
        if flip {
            return Observable.of(1,2,3)
        } else {
            return Observable.of(4,5,6)
        }
    }
    
    for _ in 0...3 {
        ob.subscribe(onNext: {
            print($0, terminator: " ")
        })
        .disposed(by: disposeBag)
        print()
    }
    
    /*
    1 2 3 
    4 5 6 
    1 2 3 
    4 5 6 
    */

    Traitの使用


    特定の用途に適したより狭い範囲の観測性

    Single

  • データまたはエラー
  • のみ解放
  • 成功(データ)(next+完了を示す)
  • 次の例
    let bag = DisposeBag()
    
    enum NetworkError: Error {
        case failToConnect
    }
    
    func getRequest(url: String?) -> Single<Bool> {
        return Single<Bool>.create { single in
            guard let url = url else {
                single(.failure(NetworkError.failToConnect))
                return Disposables.create()
            }
            
            if url == "https://www.apple.com" {
                single(.success(true))
            } else {
                single(.success(false))
            }
            
            return Disposables.create()
        }
    }
    
    getRequest(url: "https://www.apple.com")
        .subscribe(onSuccess: { success in
            print(success)
        },
        onFailure: {error in
            print(error.localizedDescription)
        },
        onDisposed: {
            print("disposed")
        })
        .disposed(by: bag)
    Result Typeみたいな感じ?

    Completable

  • 完了orエラーのみ解放
  • enum LoadingError: Error {
        case failToLoad
    }
    
    let bag = DisposeBag()
    
    func loading(complete: Bool) -> Completable {
        return Completable.create { completable in
            guard complete else {
                completable(.error(LoadingError.failToLoad))
                return Disposables.create()
            }
            
            completable(.completed)
            return Disposables.create()
        }
    }
    
    loading(complete: true)
        .subscribe {
            print("completed")
        } onError: { error in
            print(error.localizedDescription)
        }
        .disposed(by: bag)
    完了またはエラーの内容のみを解放します.値x

    Maybe

  • 成功(データ)、完了、エラー全解放
  • enum LoadingError: Error {
        case failToLoad
    }
    
    let bag = DisposeBag()
    
    func study() -> Maybe<String> {
        return Maybe<String>.create { maybe in
            maybe(.success("RxSwift"))
            maybe(.completed)
            maybe(.error(LoadingError.failToLoad))
            
            return Disposables.create()
        }
    }
    
    study()
        .subscribe { result in
            switch result {
            case .success(let language):
                print("Study " + language)
            case .completed:
                print("Completed")
            case .error(let error):
                print(error.localizedDescription)
            }
        }
        .disposed(by: bag)
    こんな感じ?

    Challenges


    do演算子


    特定のイベントが発生した場合、実行中のコールバック関数を登録します.
    変更なしに励起された要素を購読者として転送
    let bag = DisposeBag()
    
    Observable.of(1,2,3,4,5)
        .do {
            $0 * 10
        }
        .subscribe(onNext: {
            print("sub: ", $0)
        })
        .disposed(by: bag)

    デバッグ演算子

    let bag = DisposeBag()
    
    let ob = Observable<Any>.never()
        .debug("동작확인")
        .subscribe()
        .disposed(by: bag)
        
    // 2022-03-25 18:23:34.315: 동작확인 -> subscribed