UIImagePickerController (Class)
A view controller that manages the system interfaces for taking pictures, recording movies, and choosing items from the user's media library.
사용자의 미디어 라이브러리에서 사진 촬영, 동영상 녹화 및 항목 선택을 위한 시스템 인터페이스를 관리하는 보기 컨트롤러입니다.
즉, 사진 촬영, 동영상 녹화, 갤러리 선택과 관련된 걸 관리하는 컨트롤러이다.
여기보면 UIImagePickerController는 UINavigatoinController를 상속하고 있다.
또한, UIImagePickerController는 AVFoundation에 속하는데
AVFoundation은 애플에서 시청각 미디어를 검사, 재생, 캡처 및 처리하기 위한 광범위한 작업을 포괄하는 프레임워크다.
그러니까 AVFoundation은 미디어와 관련된 일을 해주는 것이다.
즉, 기본적인 것은 UIImagePickerController, 심화적인 것은 AVFoundation에서 처리해주면 된다.
문서에서 보면 몇 가지 UIImagePickerController의 특징도 나와 있는데
- 항상 세로 모드만 제공한다는 점
- SourceType이 열거형인데 camera, photoLibrary, savedPhotosAlbum이 있는데 그 중 camera를 빼고
나머지는 deprecated 되었다는 점. (deprecated 된 아이들은 PHPickerViewController를 써주면 된다.)
이 UIImagePickerController를 써주려면 어떻게 해야 할까?
문서에서 보면 UIImagePickerControllerDelegate와 UINavigationControllerDelegate 프로토콜을 채택해야 한다고 나와있다.
final class CameraViewController: UIViewController {
// MARK: - Property
// UIImagePickerController1. 인스턴스 생성
let picker = UIImagePickerController()
// MARK: - @IBOutlet
@IBOutlet weak var imageView: UIImageView!
// MARK: - LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
configureUI()
setupImagePicker()
}
// MARK: - Configure UI & Layout
private func configureUI() {
view.backgroundColor = .white
imageView.contentMode = .scaleAspectFill
}
// MARK: - @IBAction
// UIImagePickerController
@IBAction func cameraButtonClicked(_ sender: UIButton) {
guard UIImagePickerController.isSourceTypeAvailable(.camera) else {
print("사용불가 + 사용자에게 토스트/얼럿")
return
}
picker.sourceType = .camera
picker.allowsEditing = true // 사진 편집 유무
present(picker, animated: true)
}
// UIImagePickerController
@IBAction func photoLibraryButtonClicked(_ sender: UIButton) {
guard UIImagePickerController.isSourceTypeAvailable(.camera) else {
print("사용불가 + 사용자에게 토스트/얼럿")
return
}
picker.sourceType = .photoLibrary
picker.allowsEditing = true // 사진 편집 유무
present(picker, animated: true)
}
// MARK: - Custom Method
private func setupImagePicker() {
// UIImagePickerController2. 델리게이트 위임처리
picker.delegate = self
}
@IBAction func saveButtonClicked(_ sender: UIButton) {
// 이미지를 선택하고 무엇을 할 건가?에 관한 매개변수
if let image = imageView.image {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
print("🥳사진 저장했다")
}
}
}
// MARK: - UIImagePickerControllerDelegate, UINavigationControllerDelegate
// UIImagePickerController3. - 네비게이션 컨트롤러를 상속받고 있음
extension CameraViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
// UIImagePickerController4. - 사진을 선택하거나, 카메라 촬영하고 나면 호출되는 메소드
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
print(#function, "🦋 사진선택하거나, 카메라 촬영 직후")
/* 원본, 편집, 메타 데이터 등 - infoKey,
그리고 타입은 Any로 명확하게 지정되지 않았다.
왜냐하면 메타 데이터는 명확하기 않기 때문에 그래서 타입캐스팅이 필요한 부분이다. */
if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
self.imageView.image = image
dismiss(animated: true)
}
}
// UIImagePickerController5. - 취소 버튼을 누르면 호출되는 메소드
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print(#function, "🦋 취소버튼 클릭 시")
}
}
- didFinishPickingMediaWithInfo : 사진을 선택하거나, 카메라를 촬영하고 나면 호출되는 메소드
- imagePickerControllerDidCancel : 취소 버튼을 누르면 호출되는 메소드
그리고 info.plist에서 사용자의 개인 정보를 사용하는 것이기 때문에 관련 접근 권한 요청도 해야 한다.
사용자의 사진과 동영상을 저장하려고 할 경우에는, 앱에서 사용자에게 액세스 권한을 명시적으로 부여한 경우에만 가능하다.
그러나, 사진을 가져오는 것에 대한 권한은 필요가 없다. 왜냐하면 명시적으로 사용자가 선택한 사진만 가져오고, 선택한 사진에 대해 사용자가 인지하고 있기 때문이다. 갤러리를 띄우는 것도 사용자가 인지하고 있기 때문에 권한이 필요없다.
따라서, 액세스 권한에 대해 일부 허용이더라도 사진 가져오기에 권한이 필요없기 때문에 갤러리가 전부 다 보이는 것이다.
- photo Library Usage Description
- photo Library Additions Description : 사진관련 메타 데이터 등 더 많은 기능을 쓰고 통제하고 싶을 때
Q. 그렇다면 만약에 우리가 YPImagePicker라는 라이브러리를 추가해서 카메라 기능은 사용하지 않고,
갤러리 기능만 사용할 경우에 info.plist에 갤러리 접근 권한에 대한 내용만 추가해도 될까?
A. 정답은 쓰지 않더라도 무조건 등록해야 한다. 관련 코드가 들어가 있는 한 리젝 당하기 싫으면 꼭 등록해줘라.
PHPickerViewController의 등장
근데 iOS14 기준으로 PHPickerViewController가 등장했다.
기존 UIImagePickerController의 multiselect가 안되는 것과 검색 관련 지점을 보완하기 위해서 새롭게 등장했고, UIImagePickerController도 multiselect를 코드 보완을 통해서 구현할 수 있다.
따라서 iOS14부터는
카메라 촬영 - UIImagePickerController
갤러리 접근, 갤러리 저장 - UIImagePickerController
PHPickerViewController는 더 안전하고 개인 정보 보호에 집중하는 방식으로 초점이 맞춰졌다.
사용자의 갤러리에 대한 전체 액세스 권한을 부여하는 대신에 iOS는 사용자가 선택한 사진만 사용해서 공유하도록 할 수 있다.presentLimitedLibraryPicker(from:)를 사용하면 앱에서 사용할 수 있는 사진을 선택하고 나중에 이 선택 항목을 변경하면 앱에서 UI를 업데이트 하라는 알림을 받게 된다.
'⭐️ 개발 > iOS & Swift' 카테고리의 다른 글
[iOS] pngData(), jpegData(compressionQuality:) (0) | 2022.08.12 |
---|---|
[iOS] cell에 delegate, datasource 코드를 작성하지 않는 이유... 어쩌구...저쩌구... (0) | 2022.08.12 |
[iOS] 간만에 코드 자랑하기 (0) | 2022.08.10 |
[iOS] xib 사용해서 재사용 가능한 Custom View 만들기 (0) | 2022.08.10 |
[Swift] required init?(coder: NSCoder) (0) | 2022.08.10 |