Skip to content

접근 허용한 이미지 가져오는 방법

prestonk162 edited this page Dec 18, 2022 · 5 revisions

문제

PHPickerViewController와 UIImageViewController로 사진 앱에 있는 이미지들을 가져와보았는데 접근을 허용하지 않은 사진 까지 가져오는 문제가 있었다.

사실 이건 버그라기보다는 PHPickerViewController는 원래 접근 권한과 상관없이 사진 앱에 있는 모든 사진을 가져온다. (WWDC20 Meet the new Photos picker at 12:32)

PHPickerViewController를 통해 띄어지는 사진 피커는 앱의 프로세스와 별개인 프로세스로, picker(_:didFinishPicking:) 함수를 통해 선택한 사진만 앱에 전달하기 때문에, 앱은 선택된 사진만 얻게 되는 방식으로 Privacy를 보호한다.

그러나, Privacy 보호를 위해서라면, 접근을 차단한 사진을 앱 실행중에 아예 안보이게 하는게 더 맞다고 생각한다. 실제로 지하철이나 버스 등 공공장소에서 핸드폰을 켰을 때, 앱은 몰라도, 본인의 핸드폰 화면을 통해 타인이 숨길려 했던 사진을 볼 수 있기 때문이다.

해결

공식 문서와 실험을 통해, 접근 허용한 이미지를 가져오는 방법은, PHAsset, PHImageManager를 활용했다.

과정

  1. 사진 앨범에서 PHAsset 가져오기

PHAsset.fetchAssets(with:options:)함수를 이용해서 사진 앨범에 있는 사진이나 동영상을 PHAsset 형태로 가져온다. 여러 개를 가져오기 때문에 반환 값은 [PHAsset]이다.

  • PHAsset은 사진이나 동영상의 Meta 정보만 가지고 있다.
  1. PHImageManager를 통해 사진 요청 PHImageManager 객체에 requestImage(for:targetSize:contentMode:options:resultHandler:)를 통해, PHAsset에 해당하는 사진을 사진 크기 (targetSize), 사진 퀄리티 (options), 비율(contentMode) 등을 지정해서 가져올 수 있다.

그리고 클로저인 resultHandler를 통해 사진이 불러왔거나 실패했을 때 처리를 할 수 있다.

별개로 앱 실행 중 사진 앨범의 변화 (사진이 제거, 추가, 권한 변경 등)를 Observing 해서 변화가 일어날 때 앱에서도 이를 반영하는 것을 다음 방법으로 해결할 수 있다.

  1. PHPhotoLibrary에 observer로 등록 PHPhotoLibrary 객체에 register(:)를 통해 PHPhotoLibraryChangeObserver 형태의 Observer로 등록한다. 그러면 지정한 PHPhotoLibrary에 해당하는 사진 앨범에 변화가 일어나면, Delegate함수인 photoLibraryDidChange(:)에서 처리를 구현하면 된다.

결과

데모

default.mov

비교 사진

PHPickerViewController PHAsset, PHImageManager, CollectionView로 만든 커스텀 ImagePicker
스크린샷 2022-12-19 오전 1 41 33 스크린샷 2022-12-19 오전 1 42 48
Clone this wiki locally