[swift] RxCocoa를 활용한 카메라 및 갤러리 처리 방법

iOS 앱 개발에서 카메라 및 갤러리와 관련된 기능은 매우 중요합니다. 이러한 기능을 쉽게 처리하기 위해 RxCocoa를 사용할 수 있습니다. RxCocoa는 RxSwift와 함께 사용되는 라이브러리로, Reactive Programming을 통해 이벤트 기반 코드를 간결하고 효율적으로 작성할 수 있게 도와줍니다. 이번 블로그에서는 RxCocoa를 활용하여 카메라 및 갤러리 처리 방법을 알아보겠습니다.

카메라 접근 권한 확인하기

먼저, 앱에서 카메라를 사용하기 위해 접근 권한을 확인해야 합니다. RxCocoa의 UIImagePickerController를 사용하여 권한을 확인할 수 있습니다.

import UIKit
import RxCocoa
import RxSwift
import AVFoundation

func checkCameraPermission() -> Observable<Bool> {
    return Observable.create { observer in
        let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
        
        switch status {
        case .authorized:
            observer.onNext(true)
            observer.onCompleted()

        case .notDetermined:
            AVCaptureDevice.requestAccess(for: AVMediaType.video) { granted in
                observer.onNext(granted)
                observer.onCompleted()
            }

        case .denied, .restricted:
            observer.onNext(false)
            observer.onCompleted()

        @unknown default:
            observer.onNext(false)
            observer.onCompleted()
        }
        
        return Disposables.create()
    }
}

위의 코드는 checkCameraPermission 함수를 정의합니다. AVCaptureDevice.authorizationStatus(for: AVMediaType.video)를 사용하여 현재 카메라 권한 상태를 확인하고, 권한이 허용되지 않았다면 AVCaptureDevice.requestAccess(for: AVMediaType.video)를 사용하여 권한 요청 대화상자를 표시합니다. 이 함수는 Observable<Bool>을 반환하며, 권한 상태를 구독하여 사용할 수 있습니다.

카메라로 사진 찍기

카메라로 사진을 찍는 것은 RxCocoa의 UIImagePickerController를 사용하여 쉽게 처리할 수 있습니다. 필요한 코드를 살펴보겠습니다.

import RxCocoa
import RxSwift
import UIKit

class CameraViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    let imagePickerController = UIImagePickerController()
    let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupImagePickerController()
        
        navigationItem.rightBarButtonItem?.rx.tap
            .bind(onNext: { [weak self] in
                self?.openCamera()
            })
            .disposed(by: disposeBag)
    }

    func setupImagePickerController() {
        imagePickerController.delegate = self
    }

    func openCamera() {
        if UIImagePickerController.isSourceTypeAvailable(.camera) {
            imagePickerController.sourceType = .camera
            present(imagePickerController, animated: true, completion: nil)
        }
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        if let image = info[.originalImage] as? UIImage {
            // 찍은 사진 처리
        }
        
        picker.dismiss(animated: true, completion: nil)
    }
}

위의 코드에서는 CameraViewController 클래스가 UIImagePickerControllerDelegate, UINavigationControllerDelegate를 채택하고 있습니다. 먼저 imagePickerController를 생성하고, setupImagePickerController 메서드를 사용하여 UIImagePickerControllerDelegate를 설정합니다. 그리고 openCamera 메서드에서 카메라가 사용 가능한지 확인한 후, 카메라가 사용 가능하다면 UIImagePickerController를 present 합니다. 마지막으로, imagePickerController(_:didFinishPickingMediaWithInfo:) 메서드에서 사진을 처리합니다.

갤러리에서 사진 선택하기

갤러리에서 사진을 선택하는 것도 RxCocoa의 UIImagePickerController를 사용하여 쉽게 처리할 수 있습니다. 필요한 코드를 살펴보겠습니다.

import RxCocoa
import RxSwift
import UIKit

class GalleryViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    let imagePickerController = UIImagePickerController()
    let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupImagePickerController()
        
        navigationItem.rightBarButtonItem?.rx.tap
            .bind(onNext: { [weak self] in
                self?.openGallery()
            })
            .disposed(by: disposeBag)
    }

    func setupImagePickerController() {
        imagePickerController.delegate = self
    }

    func openGallery() {
        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
            imagePickerController.sourceType = .photoLibrary
            present(imagePickerController, animated: true, completion: nil)
        }
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        if let image = info[.originalImage] as? UIImage {
            // 선택한 사진 처리
        }
        
        picker.dismiss(animated: true, completion: nil)
    }
}

위의 코드에서는 GalleryViewController 클래스가 UIImagePickerControllerDelegate, UINavigationControllerDelegate를 채택하고 있습니다. 마찬가지로 imagePickerController를 생성하고, setupImagePickerController 메서드를 사용하여 UIImagePickerControllerDelegate를 설정합니다. openGallery 메서드에서는 갤러리가 사용 가능한지 확인한 후, 사용 가능하다면 UIImagePickerController를 present 합니다. 마지막으로, imagePickerController(_:didFinishPickingMediaWithInfo:) 메서드에서 선택한 사진을 처리합니다.

결론

RxCocoa를 사용하여 iOS 앱에서 카메라 및 갤러리 기능을 처리하는 방법을 알아보았습니다. checkCameraPermission 함수를 사용하여 앱의 카메라 권한을 확인하고, UIImagePickerController를 사용하여 카메라로 사진을 찍거나 갤러리에서 사진을 선택할 수 있습니다. 이러한 기능을 활용하여 사용자에게 편리하고 간편한 사진 기능을 제공할 수 있습니다.

이러한 방법을 참고하여 개발하면서 RxCocoa를 활용하여 카메라 및 갤러리와 관련된 기능을 효율적으로 처리할 수 있습니다.