[swift] RxCocoa를 활용한 사진 및 동영상 처리 방법

RxCocoa는 RxSwift의 확장 라이브러리로, iOS 및 macOS 애플리케이션 개발에 사용되는 반응형 프로그래밍 패턴을 더욱 쉽게 구현할 수 있게 도와줍니다. 이번 포스트에서는 RxCocoa를 사용하여 사진 및 동영상을 처리하는 방법을 살펴보겠습니다.

1. 사진 가져오기

RxCocoa를 사용하여 사진을 가져오려면 UIImagePickerControllerDelegate 프로토콜을 구현해야 합니다. 먼저 UIImagePickerController를 생성하고, delegate를 self로 설정합니다. 그리고 UIImagePickerControllerDelegateimagePickerController(_:didFinishPickingMediaWithInfo:) 메서드를 구현하여 선택한 이미지를 처리합니다.

import RxSwift
import RxCocoa
import UIKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    let disposeBag = DisposeBag()
    
    var imagePicker = UIImagePickerController()
    var selectedImage = PublishRelay<UIImage>()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        imagePicker.delegate = self
        
        // 사진 가져오기 버튼
        let button = UIButton(type: .system)
        button.setTitle("사진 가져오기", for: .normal)
        
        button.rx.tap
            .flatMapLatest { [weak self] _ -> Observable<UIImage> in
                guard let self = self else { return .empty() }
                
                return self.imagePicker.rx.didFinishPickingMediaWithInfo
                    .map { info in
                        if let image = info[.originalImage] as? UIImage {
                            return image
                        } else {
                            throw RxCocoaExampleError.invalidImage
                        }
                    }
            }
            .bind(to: selectedImage)
            .disposed(by: disposeBag)
    }
    
    // 사진 선택이 완료된 후 호출되는 메서드
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        guard let image = info[.originalImage] as? UIImage else { return }
        
        selectedImage.accept(image)
        picker.dismiss(animated: true, completion: nil)
    }
}

위 코드에서 button.rx.tap으로 버튼의 탭 이벤트를 구독합니다. flatMapLatest 연산자를 사용하여 선택한 사진을 처리합니다. imagePicker.rx.didFinishPickingMediaWithInfo를 옵저버블로 변환하고, 선택한 이미지를 반환합니다. 마지막으로 bind(to:)를 사용하여 선택한 이미지를 selectedImage 프로퍼티에 바인딩합니다.

2. 동영상 가져오기

RxCocoa를 사용하여 동영상을 가져오려면 마찬가지로 UIImagePickerControllerDelegate 프로토콜을 구현해야 합니다. 하지만 사진과는 다르게 UIImagePickerControllermediaTypes 속성을 설정하고, UIImagePickerControllerDelegateimagePickerController(_:didFinishPickingMediaWithInfo:) 메서드 안에서 다른 키를 사용하여 동영상을 처리해야 합니다.

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    let disposeBag = DisposeBag()
    
    var imagePicker = UIImagePickerController()
    var selectedVideo = PublishRelay<URL>()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        imagePicker.delegate = self
        imagePicker.mediaTypes = ["public.movie"]
        
        // 동영상 가져오기 버튼
        let button = UIButton(type: .system)
        button.setTitle("동영상 가져오기", for: .normal)
        
        button.rx.tap
            .flatMapLatest { [weak self] _ -> Observable<URL> in
                guard let self = self else { return .empty() }
                
                return self.imagePicker.rx.didFinishPickingMediaWithInfo
                    .map { info in
                        if let videoURL = info[.mediaURL] as? URL {
                            return videoURL
                        } else {
                            throw RxCocoaExampleError.invalidVideo
                        }
                    }
            }
            .bind(to: selectedVideo)
            .disposed(by: disposeBag)
    }
    
    // 동영상 선택이 완료된 후 호출되는 메서드
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        guard let videoURL = info[.mediaURL] as? URL else { return }
        
        selectedVideo.accept(videoURL)
        picker.dismiss(animated: true, completion: nil)
    }
}

위 코드에서는 imagePicker.mediaTypes 속성을 설정하여 동영상 타입을 지정합니다. 그리고 imagePickerController(_:didFinishPickingMediaWithInfo:) 메서드에서 .mediaURL을 사용하여 동영상 URL을 가져옵니다.

이와 같이 RxCocoa를 사용하여 사진 및 동영상을 처리하는 방법을 알아보았습니다. RxCocoa는 반응형 프로그래밍 패턴을 쉽게 구현할 수 있도록 도와주므로, 애플리케이션에서 사진이나 동영상과 같은 미디어 처리에 유용하게 사용할 수 있습니다.

참고 자료