[swift] RxCocoa를 이용한 파일 다운로드 처리 방법

RxCocoa는 RxSwift를 기반으로한 Cocoa 프레임워크를 제공하는 라이브러리로, iOS 및 macOS 애플리케이션 개발에 사용됩니다. 이번 포스트에서는 RxCocoa를 이용하여 파일 다운로드를 처리하는 방법에 대해 알아보겠습니다.

1. URLSession과 RxCocoa를 import 하기

import UIKit
import RxSwift
import RxCocoa

2. 파일 다운로드 함수 만들기

func downloadFile(from url: URL) -> Observable<URL> {
    return Observable<URL>.create { observer in
        let task = URLSession.shared.downloadTask(with: url) { (location, response, error) in
            if let error = error {
                observer.onError(error)
                return
            }

            guard let location = location else {
                observer.onError(NSError(domain: "Download Error", code: 0, userInfo: nil))
                return
            }

            do {
                let documentsURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
                let destinationURL = documentsURL.appendingPathComponent(response?.suggestedFilename ?? url.lastPathComponent)
                try FileManager.default.moveItem(at: location, to: destinationURL)
                observer.onNext(destinationURL)
                observer.onCompleted()
            } catch {
                observer.onError(error)
            }
        }

        task.resume()

        return Disposables.create {
            task.cancel()
        }
    }
}

위의 함수는 주어진 URL에서 파일을 다운로드하고, 다운로드한 파일의 저장 경로를 반환하는 Observable을 생성합니다.

3. 버튼 액션에 Observable 바인딩하기

@IBOutlet weak var downloadButton: UIButton!

let disposeBag = DisposeBag()

override func viewDidLoad() {
    super.viewDidLoad()

    downloadButton.rx.tap
        .flatMapLatest { [weak self] _ in
            guard let url = URL(string: "https://example.com/example.pdf") else {
                return Observable.error(NSError(domain: "Invalid URL", code: 0, userInfo: nil))
            }
            return self?.downloadFile(from: url) ?? Observable.empty()
        }
        .observeOn(MainScheduler.instance)
        .subscribe(onNext: { [weak self] destinationURL in
            // 다운로드 완료 처리
        }, onError: { error in
            // 에러 처리
        })
        .disposed(by: disposeBag)
}

위의 코드에서는 downloadButton의 tap 이벤트를 감지하여, 주어진 URL에서 파일을 다운로드하는 작업을 수행합니다. 다운로드가 성공하면 onNext 클로저가 호출되며, 다운로드 중 발생한 에러는 onError 클로저를 통해 처리됩니다.

이제 RxCocoa를 이용하여 파일 다운로드를 처리하는 방법에 대해 알아보았습니다. RxCocoa를 사용하면 비동기적인 작업을 조금 더 간결하고 효율적으로 처리할 수 있으며, 코드의 가독성을 향상시킬 수 있습니다.

참고 자료