iOS/RxSwift

[RxSwift] Single, Maybe, Completable 알아보기

728x90

✨  Single, Maybe, Completable: 좁은 범위의 Observable, 코드 가독성 높임

Single

: 정확히 한가지 요소만을 방출

  • .success: next + complete
  • .error

ex) 사진 다운로드(성공/실패 여부 판단)

Maybe

: Single과 비슷하지만 .completed을 포함함

  • .success
  • .completed
  • .error

Completable

: 어떠한 값도 방출하지 않음

  • .completed: 아무런 값을 방출하지 않음
  • .error

✨  Observable을 as Single, as Maybe를 통해 변환이 가능하지만 as Completable은 불가능함, create로 생성해야함

 

실습해보기

import RxSwift
import Foundation

let disposeBag = DisposeBag()

enum TraitsError: Error{
    case single
    case maybe
    case completable
}

//📌 Single
print("----Single1----")
Single<String>.just("✅")
    .subscribe(
        onSuccess: { // onNext + onCompleted
            print($0)
        },
        onFailure: {
            print("error: \($0)")
        },
        onDisposed: {
            print("disposed")
        }
    )
    .disposed(by: disposeBag)

print("----Single2----")
Observable<String>
    .create{ observer -> Disposable in
        observer.onError(TraitsError.single)
        return Disposables.create()
    }
    .asSingle()
    .subscribe(
        onSuccess: { // onNext + onCompleted
            print($0)
        },
        onFailure: {
            print("error: \($0.localizedDescription)")
        },
        onDisposed: {
            print("disposed")
        }
    )
    .disposed(by: disposeBag)

print("----Single3----")
struct SomeJson: Decodable{
    let name: String
}

enum JSONError: Error{
    case decodingError
}

let json1 = """
    {"name": "park"}
    """
let json2 = """
    {"my_name": "young"}
    """

// JSON 디코딩
func decode(json: String) -> Single<SomeJson>{
    Single<SomeJson>.create{observer -> Disposable in
        guard let data = json.data(using: .utf8),
              let json = try? JSONDecoder().decode(SomeJson.self, from: data) else{
            // 실패
            observer(.failure(JSONError.decodingError))
            return Disposables.create()
        }
        // 성공
        observer(.success(json))
        return Disposables.create()
    }
}

decode(json: json1)
    .subscribe{
        switch $0{
        case .success(let json):
            print(json.name)
        case .failure(let error):
            print(error)
        }
    }
    .disposed(by: disposeBag)

decode(json: json2)
    .subscribe{
        switch $0{
        case .success(let json):
            print(json.name)
        case .failure(let error):
            print(error)
        }
    }
    .disposed(by: disposeBag)

//📌 MayBe
print("----Maybe1----")
Maybe<String>.just("✅")
    .subscribe(
        onSuccess: {
            print($0)
        },
        onError: {
            print("error: \($0)")
        },
        onCompleted: {
            
        },
        onDisposed: {
            print("disposed")
        }
    )
    .disposed(by: disposeBag)

print("----Maybe2----")
Observable<String>
    .create{ observer -> Disposable in
        observer.onError(TraitsError.single)
        return Disposables.create()
    }
    .asMaybe()
    .subscribe(
        onSuccess: {
            print($0)
        },
        onError: {
            print("error: \($0)")
        },
        onCompleted:{
            print("completed")
        },
        onDisposed: {
            print("disposed")
        }
    )
    .disposed(by: disposeBag)

//📌 Completable
print("----Completable1----")
//✨ asSingle, asMaybe처럼 asCompetable 키워드 사용 불가능 -> 반드시 create로만 만들어주기!
Completable.create { completable in
    completable(.error(TraitsError.completable))
    return Disposables.create()
}
.subscribe(onCompleted: {
    print("completed")
}, onError: {
    print("error: \($0.localizedDescription)")
}, onDisposed: {
    print("disposed")
})
.disposed(by: disposeBag)

print("----Completable2----")
Completable.create { completable in
    completable(.completed)
    return Disposables.create()
}
.subscribe(onCompleted: {
    print("completed")
}, onError: {
    print("error: \($0.localizedDescription)")
}, onDisposed: {
    print("disposed")
})
.disposed(by: disposeBag)

 

실행 결과

----Single1----
✅
disposed
----Single2----
error: The operation couldn’t be completed. (__lldb_expr_25.TraitsError error 0.)
disposed
----Single3----
park
decodingError
----Maybe1----
✅
disposed
----Maybe2----
error: single
disposed
----Completable1----
error: The operation couldn’t be completed. (__lldb_expr_25.TraitsError error 2.)
disposed
----Completable2----
completed
disposed
728x90

'iOS > RxSwift' 카테고리의 다른 글

[RxSwift] Transforming Operator 알아보기  (0) 2022.10.23
[RxSwift] Filtering Operator 알아보기  (1) 2022.10.23
[RxSwift] Subject 알아보기  (0) 2022.08.14
[RxSwift] Observable 알아보기  (0) 2022.08.11
[RxSwift] RxSwift란?  (0) 2022.07.31