본문 바로가기

iOS/Swift

[SwiftUI] UIImagePickerController를 이용한 카메라 사용

안녕하세요. 이번에는 SwiftUI에서 카메라를 사용하는 방법을 다뤄보겠습니다.

먼저 카메라를 사용하기 위해서는 사용자가 카메라 사용 권한을 허용해야합니다.

 

//권한 여부 확인
let status = AVCaptureDevice.authorizationStatus(for: .video)

if status == .authorized {
	//TODO: 카메라 접근 권한이 이미 허용 상태인 경우
} else if status == .notDetermined {
    AVCaptureDevice.requestAccess(for: .video) { accessGranted in
        DispatchQueue.main.async {
            if accessGranted {
            	//TODO: 지금 카메라 접근 권한을 허용한 경우
            } else {
                //TODO: 카메라 접근 권한 거부 상태인 경우
            }
        }
    }
} else {
    //TODO: 카메라 접근 권한 거부 상태인 경우
}

 

카메라 권한 상태는 AVCaptureDevice.authorizationStatus 메소드를 이용하여 확인합니다. 이 때, for 매개변수로 AVMediaType.video를 넘겨주면 카메라 권한 상태를 가져올 수 있습니다. 권한 상태는 다음과 같습니다.

  • AVAuthorizationStatus.authorized : 권한 허용 상태
  • AVAuthorizationStatus.notDetermined: 사용자가 아직 이 앱에 대한 권한을 설정하지 않은 상태
  • AVAuthorizationStatus.restricted, AVAuthorizationStatus.denied: 권한 거부 상태

이렇게 사용자가 카메라 권한을 허용했다면, 이제 카메라를 사용해야겠죠?

아쉽게도 지금은 SwiftUI로 카메라 뷰가 구현되어있지는 않습니다. 따라서 iOS 앱을 개발하면서 카메라를 사용하는 방법은 현재 두 가지가 있는데요. UIImagePickerController를 사용하는 방법과, AVFoundation을 이용해 카메라 화면을 직접 구현하는 방법이 있습니다. 이번에 저는 UIImagePickerController를 사용해보도록 하겠습니다.

 

import SwiftUI

class ImagePickerCoordinator: NSObject, UIImagePickerControllerDelegate {
    
    @Binding var image: UIImage
    @Binding var isActive: Bool
    
    init(image: Binding<UIImage>, isActive: Binding<Bool>) {
        _image = image
        _isActive = isActive
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let uiImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {            
            image = uiImage
            isActive = false
        }
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        isActive = false
    }
}

struct ImagePicker: UIViewControllerRepresentable {
    typealias UIViewControllerType = UIImagePickerController
    typealias Coordinator = ImagePickerCoordinator
    
    //coordinator
    @Binding var image: UIImage
    @Binding var isActive: Bool
    
    var sourceType: UIImagePickerController.SourceType = .camera
    
    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.sourceType = sourceType
        picker.delegate = context.coordinator
        
        return picker
    }
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {
        //do nothing
    }
    
    func makeCoordinator() -> ImagePicker.Coordinator {
        return ImagePickerCoordinator(image: $image, isActive: $isActive)
    }
}

 

UIImagePickerController는 이름에서 알 수 있듯이 UIViewController 이고, SwiftUI 에서 이를 사용하기 위해 UIViewControllerRepresentable을 구현했습니다. 이 때, UIImagePickerDelegate를 사용하여 사진을 찍고 확인을 눌렀을 때의 처리와 취소 버튼을 눌렀을 때의 처리를 구현했습니다. 이제 이 뷰를 NavigationLink나 .fullScreenCover 등으로 화면 전환을 구현해주면 카메라를 사용할 수 있습니다.

'iOS > Swift' 카테고리의 다른 글

[Swift] 사진 가져오기  (0) 2022.04.04