본문 바로가기
💡 Today I Learned/스터디 자료정리

[스터디11일차][RxSwift] Traits

by 솔비님 2025. 2. 7.

Traits란?

특정한 상황에서 사용하기 쉽게 미리 정의된 Observable의 특별한 형태
Single, CompletableMaybe 세 가지 종류가 있다

 

 

 


Single: 한 번만 값을 방출한다

오직 하나의 값(.success(value)) 또는 에러(.failure(error))를 방출하는 Observable
자동으로 완료되며 값을 받고나면 더이상 방출되지 않는다

 예제 1 - just 

정해진 값을 그대로 반환할 때 사용

import RxSwift

let single = Single.just("Hello, Single!")

single.subscribe(onSuccess: { value in
    print(value)
})

 

 예제 2 - create 

비동기 작업과 같은 상황에서 사용된다(ex. API 요청)

요청 성공 시 single(.success())로 성공 값을 반환하고, 요청 실패 시 single(.failure))로 에러를 반환한다

let single = Single<String>.create { single in
    let success = true // 응답이 성공했다고 가정

    if success {
        single(.success("네트워크 데이터"))
    } else {
        single(.failure(NSError(domain: "NetworkError", code: -1, userInfo: nil)))
    }

    return Disposables.create()
}

 

 예제 3 - from 

배열에서 첫번째 값만 필요할 때 사용한다

let single = Single.from(["A", "B", "C"])

 

 

 


Completable: 성공 또는 실패만 있다

Completable은 성공(.completed) 또는 실패(.error)만 전달하는 특수한 Observable
값을 방출하지 않기 때문에, 성공/실패 여부가 중요한 작업에서 사용한다

 예제 - 네트워크 요청 구현 

로직 이해하기!!

  1. 아래 예제에서 sendDataToServer()를 호출하면 Completable이 반환되면서 함수 내부 로직이 실행됨
  2. 함수 내부에서 네트워크 성공/실패 여부를 판단하고 성공 시 .completed가 호출되고, 실패 시 .error가 호출되면서 성공/실패 여부가 구독자에게 전달됨
  3. .subscribe한 구독자는 성공/실패 여부를 전달받고 상황에 맞는 이벤트를 방출함
import RxSwift

// ✅ 네트워크 요청을 Completable로 구현
func sendDataToServer() -> Completable {
    return Completable.create { completable in
        print("🌍 서버에 데이터 전송 중...")

        let isSuccess = Bool.random() // 네트워크 성공 여부를 랜덤으로 설정

        DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) { // 비동기 네트워크 요청 시뮬레이션
            if isSuccess {
                completable(.completed) // 네트워크 요청 성공 시 구독자에게 .completed를 전달
            } else {
                completable(.error(NSError(domain: "NetworkError", code: -1, userInfo: nil))) // 네트워크 요청 실패 시 구독자에게 .error를 전달
            }
        }

        return Disposables.create()
    }
}

// ✅ 네트워크 요청 실행 & 구독
sendDataToServer()
    .subscribe(
        onCompleted: {
            print("✅ 서버에 데이터 전송 완료!")
        },
        onError: { error in
            print("❌ 서버에 데이터 전송 실패: \(error.localizedDescription)")
        }
    )

 

 

 


Maybe: 값이 있을 수도, 없을 수도 있다

값을 하나(.success(value)) 또는 없음(.completed) 또는 에러(.error(error))를 방출하는 Observable
값이 없을 수도 있다(Single과 Completable의 중간 형태)

 예제 - 캐시에서 데이터 가져오기 

로직 이해하기!!

  1. 아래 예제에서 fetchCacheData()를 호출하면 함수 내부 로직이 실행됨
  2. 아래 예제는 저장된 캐시 데이터가 있다고 가정함
  3. 데이터가 있을 경우 .succsee 반환, 없을 경우 .completed가 호출되면서 값 없이 완료처리
  4. .subscribe한 구독자는 데이터 유무를 전달받고 상황에 맞는 이벤트를 방출함
func fetchCachedData() -> Maybe<String> {
    return Maybe<String>.create { maybe in
        let cachedData: String? = "저장된 데이터" // 캐시 데이터가 있다고 가정

        if let data = cachedData {
            maybe(.success(data)) // 성공: 값 반환
        } else {
            maybe(.completed) // 값 없이 완료
        }

        return Disposables.create()
    }
}

fetchCachedData()
    .subscribe(onSuccess: { data in
        print("✅ 캐시 데이터: \(data)")
    })