개발

RxSwift Observables

한번사는인생~키야 2024. 7. 9. 12:24
728x90

RxSwift는 복잡하고 반응형 애플리케이션을 구축할 수 있는 풍부한 기능과 개념을 제공합니다. 다음은 다양한 시나리오와 과제를 처리하기 위해 RxSwift Observables를 사용하는 방법에 대한 몇 가지 심층적인 예입니다.

1. RxSwift로 타이머 구현:

  • RxSwift는 타이머를 만들고 관리하기 위한 기본 제공 연산자를 제공합니다.
import RxSwift



let timerObservable = Observable<Int>.interval(1, scheduler: SerialDispatchQueueScheduler(qos: .background))

  .map { $0 + 1 }



timerObservable.subscribe(onNext: { count in

  print("Time elapsed: \(count) seconds")

})

 

  • 이 코드는 1부터 시작하여 1초마다 숫자를 방출하는 Observable을 생성합니다 .
  • 작업자 interval는 1초 간격으로 타이머를 만듭니다.
  • 연산자 map는 발생된 숫자를 증가시켜 경과 시간을 나타냅니다.
  • 클로저 subscribe는 경과 시간을 콘솔에 출력합니다.

2. RxSwift로 사용자 제스처 처리:

  • RxSwift는 사용자 상호작용을 처리하기 위해 다양한 UIKit 컨트롤에 대한 확장 기능을 제공합니다.
import RxSwift



let button = UIButton()



let buttonTapObservable = button.rx.tap



buttonTapObservable.subscribe(onNext: { _ in

  print("Button tapped!")

  // Perform an action when the button is tapped

})

 

  • 이 코드는 탭될 때마다 이벤트를 발생시키는 Observable을 생성합니다 .button
  • subscribe버튼을 탭하면 클로저가 호출되어 원하는 작업을 수행할 수 있습니다.

3. RxSwift로 드래그 앤 드롭 기능 구현:

  • RxSwift를 사용하면 뷰 간의 드래그 앤 드롭 상호작용을 처리할 수 있습니다.
import RxSwift



let sourceView = UIView()

let destinationView = UIView()



let dragGestureRecognizer = UIPanGestureRecognizer()

sourceView.addGestureRecognizer(dragGestureRecognizer)



let dragObservable = dragGestureRecognizer.rx.event

  .filter { $0.state == .began }

  .map { $0.location(in: sourceView) }



dragObservable.subscribe(onNext: { location in

  // Handle the drag start event with the initial location

})



let dropObservable = destinationView.rx.event

  .filter { $0.type == .touchEnded }

  .map { $0.location(in: destinationView) }



dropObservable.subscribe(onNext: { location in

  // Handle the drop event with the final location

})
  • 이 코드는 드래그 시작 및 드롭 이벤트에 대한 Observables를 생성합니다.
  • 드래그가 시작되면 초기 터치 위치가 방출됩니다 .dragObservable
  • 드래그가 대상 뷰에서 끝나면 최종 터치 위치를 방출합니다 .dropObservable
  • 이러한 Observable을 사용하여 드래그 앤 드롭 로직을 처리할 수 있습니다.

4. 사용자 정의 오류 처리 메커니즘 구현:

  • RxSwift는 오류를 처리하고 실패한 작업을 다시 시도하기 위한 연산자를 제공합니다.
import RxSwift



let networkRequestObservable = Observable<Data>.create { observer in

  // Perform network request and send the data or error to the observer

}



networkRequestObservable

  .retryWhen { observableErrors -> Observable<Int> in

    observableErrors

      .flatMap { error -> Observable<Int> in

        if let retryCount = error.userInfo?["RetryCount"] as? Int, retryCount < 3 {

          return Observable.just(retryCount + 1) // Retry the request with a delay

        } else {

          return Observable.error(error) // Give up after 3 retries

        }

      }

      .delay(1, scheduler: SerialDispatchQueueScheduler(qos: .background))

  }

  .subscribe(onNext: { data in

    print("Received data: \(data)")

  }, onError: { error in

    print("Error: \(error.localizedDescription)")

  })

 

  • 이 코드는 네트워크 요청에 대한 Observable을 생성합니다.
  • 운영자는 retryWhen재시도 전략을 정의합니다.
  • 오류 정보를 확인 RetryCount하고 1초 지연으로 최대 3번까지 요청을 다시 시도합니다.
  • 최대 재시도 횟수에 도달하면 오류가 클로저로 전파됩니다 onError.

5. 백그라운드 작업을 위한 사용자 정의 스케줄러 구현:

  • RxSwift는 백그라운드 작업을 처리하고 UI 업데이트를 주 스레드로 전달하는 데 도움이 되는 사용자 정의 스케줄러를 만드는 기능을 제공합니다. 이를 통해 UI 스레드를 방해하지 않고 효율적으로 백그라운드 작업을 수행할 수 있습니다.

 

5.1. SerialDispatchQueueScheduler 사용:

import RxSwift



// 백그라운드 작업을 처리할 시리얼 큐 생성

let backgroundQueue = DispatchQueue.global(qos: .background)



// 백그라운드 작업을 처리하는 사용자 정의 스케줄러 생성

let backgroundScheduler = SerialDispatchQueueScheduler(queue: backgroundQueue)



// 백그라운드 작업을 수행하는 Observable 생성

let backgroundTaskObservable = Observable<Int>.create { observer in

  backgroundScheduler.schedule {

    // 백그라운드 작업 수행

    for index in 0..<10 {

      observer.on(.next(index))

      Thread.sleep(forTimeInterval: 0.5) // 작업 지연

    }

    observer.on(.completed)

  }

}



// 백그라운드 작업 결과를 주 스레드에서 처리

backgroundTaskObservable

  .observe(on: MainScheduler.instance) // 주 스레드로 작업 전환

  .subscribe(onNext: { index in

    print("Received index on main thread: \(index)")

  }, onCompleted: {

    print("Background task completed")

  })

 

2. ConcurrentDispatchQueueScheduler를 사용.

import RxSwift



// 동시에 여러 작업을 처리할 수 있는 백그라운드 큐 생성

let backgroundQueue = DispatchQueue.global(qos: .background)



// 동시에 여러 작업을 처리하는 사용자 정의 스케줄러 생성

let backgroundScheduler = ConcurrentDispatchQueueScheduler(queue: backgroundQueue)



// 백그라운드 작업을 수행하는 Observable 생성

let backgroundTaskObservable = Observable<Int>.create { observer in

  backgroundScheduler.schedule {

    // 동시에 여러 작업 수행

    for index in 0..<10 {

      backgroundScheduler.schedule {

        observer.on(.next(index))

        Thread.sleep(forTimeInterval: 0.5) // 작업 지연

      }

    }

    observer.on(.completed)

  }

}



// 백그라운드 작업 결과를 주 스레드에서 처리

backgroundTaskObservable

  .observe(on: MainScheduler.instance) // 주 스레드로 작업 전환

  .subscribe(onNext: { index in

    print("Received index on main thread: \(index)")

  }, onCompleted: {

    print("Background task completed")

  })

 

3. 사용자 정의 스케줄러 활용:

  • 백그라운드 작업의 특성에 맞춰 SerialDispatchQueueScheduler 또는 ConcurrentDispatchQueueScheduler 중 선택
  • 작업의 순서가 중요한 경우 SerialDispatchQueueScheduler 사용
  • 동시에 여러 작업을 처리해야 하는 경우 ConcurrentDispatchQueueScheduler 사용
  • 필요에 따라 사용자 정의 스케줄러를 확장하여 특정 작업을 처리하도록 구현 가능