본문 바로가기
iOS/RxSwift

RxSwift: Observable

by HaningYa 2020. 7. 9.
728x90

Observable 만들기

기본적으로 observable 은 subscribe 하지 않으면 동작하지 않는다.

subscribe 를 하면 element 가 하나씩 emit 되며 마지막에 completed 로 마무리 된다.

  • just: 하나의 항목을 추가한다.
  • of: single element로다 집어 넣는다.
  • from: individual elements from an array of typed elements
func createObservable() {
        let one = 1
        let two = 2
        let three = 3
        
        let observable = Observable<Int>.just(one)
        let observable2 = Observable.of(one,two,three)
        let observable3 = Observable.of([one,two,three])
        let observable4 = Observable.from([one,two,three])
        
        observable.subscribe( {event in
            print("observable: \(event)")
        })
        //observable: next(1)
        //observable: completed
        observable2.subscribe( { event in
            print("observable2: \(event)")
        })
        //observable2: next(1)
        //observable2: next(2)
        //observable2: next(3)
        //observable2: completed
        observable3.subscribe( { event in
            print("observable3: \(event)")
        })
        //observable3: next([1, 2, 3])
        //observable3: completed
        observable4.subscribe( { event in
            print("observable4: \(event)")
        })
        //observable4: next(1)
        //observable4: next(2)
        //observable4: next(3)
        //observable4: completed
    }

Element

element 를 사용하면 값만 가져올 수 있다.

observable2.subscribe { event in
            if let element = event.element {
                print(element)
            }
        }
//        1
//        2
//        3

OnNext

observable2.subscribe(onNext : {element in
            print(element)
        })
//        1
//        2
//        3

OnCompleted 를 따로 처리해 주고 싶다면

func practiceObservable(){
        let one = 1
        let two = 2
        let three = 3
        let observable2 = Observable.of(one,two,three)
        
        observable2.subscribe(
            onNext: { element in
                print(element)
        },
            onCompleted: {
                print("Completed")
        })
    }
//1
//2
//3
//Completed

Disposing and termination

func disposePractice(){
        let disposeBag = DisposeBag()
        //when use disposeBag
        Observable.of("A","B","C")
            .subscribe {
                print($0)
        }
        .disposed(by: disposeBag)
        //when not use disposeBag --> subscribe operater return a disposable
        Observable<String>.create { observer in
            observer.onNext("1")
            observer.onCompleted()
            observer.onNext("?")
            return Disposables.create()
        }.subscribe(
            onNext: {print($0)},
            onError: {print($0)},
            onCompleted: {print("complemted")},
            onDisposed: {print("Disposed")}
        )
//        1
//        complemted
//        Disposed
        
    }

Observable Factories

func observableFactories(){
        //return different observables based on whether flip is true or false
        let disposeBag = DisposeBag()
        var flip = false
        let factory: Observable<Int> = Observable.deferred {
            flip.toggle()
            if flip {
                return Observable.of(1,2,3)
            }else {
                return Observable.of(4,5,6)
            }
        }
        
        for _ in 0...3 {
            factory.subscribe(onNext: {
                print($0,terminator: "")
            })
            .disposed(by: disposeBag)
            print()
        }
    }

Observable Traits

  • Single: .success, .error / one-time process what will either succeed and yield a value of fail (downloading data)
  • Maybe: mashup of Single and Completable, succeed or fail, optionally return value on success
  • Completable: .complete, .error / dont' emit any value (file write)

Single 예시(read Copyright.txt)

func singleTrait() {
        let disposeBag = DisposeBag()
        enum FileReadError : Error {
            case fileNotFound, unreadable, encodingFailed
        }
        func loadText(from name: String) -> Single<String> {
            return Single.create{ single in
                let disposable = Disposables.create()
                guard let path  = Bundle.main.path(forResource: name, ofType: "txt") else {
                    single(.error(FileReadError.fileNotFound))
                    return disposable
                }
                guard let data = FileManager.default.contents(atPath: path) else {
                    single(.error(FileReadError.unreadable))
                    return disposable
                }
                guard let contents = String(data: data, encoding: .utf8) else{
                    single(.error(FileReadError.encodingFailed))
                    return disposable
                }
                single(.success(contents))
                return disposable
            }
        }
        
        loadText(from: "Copyright")
            .subscribe {
                switch $0 {
                case .success(let string) :
                    print(string)
                case .error(let err):
                    print(err)
                }
        }
        .disposed(by: disposeBag)
    }

Challenge 1

observable 에 "do"를 통해 side effect 를 넣고 onSubscribe handler 를 포함시켜라

disposebag으로 dispose 도 해라

func challenge1(){
        let observable = Observable.of(1,2,3,4)
        let disposeBag = DisposeBag()
        
        observable
            .do(onSubscribe: {
                print("its subscribed")
            })
          .subscribe(
            onNext: { element in
              print(element)
            },
            onCompleted: {
              print("Completed")
            },
            onDisposed: {
              print("Disposed")
            }
          )
            .disposed(by: disposeBag)
    }
    
//its subscribed
//1
//2
//3
//4
//Completed
//Disposed

Challenge 2

Rxcode 를 debug 하는 연습이다.

debug operator를 사용해 obervable의 모든 even 에 대핸 information을 출력해봐라

  func challenge2(){
        let observable = Observable.of(1,2,3,4)
        let disposeBag = DisposeBag()
        
        observable
            .debug("observable")
            .subscribe(
                onNext: { element in
                    print(element)
            },
                onCompleted: {
                    print("Completed")
            },
                onDisposed: {
                    print("Disposed")
            }
        )
            .disposed(by: disposeBag)
//        2020-07-09 19:05:40.232: observable -> subscribed
//        2020-07-09 19:05:40.234: observable -> Event next(1)
//        1
//        2020-07-09 19:05:40.234: observable -> Event next(2)
//        2
//        2020-07-09 19:05:40.234: observable -> Event next(3)
//        3
//        2020-07-09 19:05:40.234: observable -> Event next(4)
//        4
//        2020-07-09 19:05:40.235: observable -> Event completed
//        Completed
//        Disposed
//        2020-07-09 19:05:40.235: observable -> isDisposed

    }

 

 

 

 

728x90

댓글