회사에서 업무를 진행하며, 이미지 피커를 통해 여러장의 사진을 선택하고, 이를 엔진(서버)에 올려야하는 테스크를 맡게 되어 이를 해결했던 과정들을 상세하게 적어보고자 합니다.

기존에는, UIImagePickerController의 SourceType을 photoLibrary 로 지정하면 우리가 흔히 보는 이미지 피커의 모습을 볼 수 있었습니다.
그러나, 애플에서 지원해주던 이미지 피커의 결정적인 단점이 두가지가 있었는데
1) 이미지가 여러장 선택이 되지 않는다는 단점과
2) iOS 15부턴 Deprecated가 된 단점이 있었습니다.
ELCImagePickerController를 쓰라는 답이 달린 것을 보면, 당시 프로덕트를 제작할 때 해당 이미지 피커를 활용하는게 최선의 방법이었던 것 같습니다.

UIImagePickerController의 공식문서에서도 언급되었듯이, iOS 14부터 PHPickerViewController을 사용하도록 가이드가 되어 있습니다.
PHPickerViewController을 통해 여러장의 이미지 업로드 등, 회사에서 요구하는 사항들을 충족할 수 있을 것 같아, 이번 포스팅에서는 PHPickerViewController에 대해 이야기 해보고자 합니다.
공식 문서에서도 확인 가능하듯이, PHPickerViewController은 UIImagePickerController의 대안으로 나온 것입니다.
기존 피커에 비해 많은 개선점들이 있지만, 대표적으론 밑의 두가지가 있습니다.
1) 파노라마 같은 규모가 크고, 복잡한 Asset의 용이한 처리가 가능
2) UIImagePickerController에서 사용할 수 없었던 Asset의 선택

PHPickerViewController 객체를 생성하는 과정에서 생성 인자로 PHPickerConfiguration을 받고 있기 때문에, 사용하고자 하는 피커의 실체화 전에 우선적으로 피커의 Configuration을 미리 만들어야 합니다.
PHPickerConfiguration 의 공식문서에 명시되어 있는 것처럼, 피커를 활용하기 전에 어떻게 구성을 할 것인가에 대한 정보를 담는 것이 PHPickerConfiguration이며, 보통은 객체를 생성하여 설정 값들을 하나씩 하나씩 추가하는 형태로 이루어집니다.
//Objective C
PHPickerConfiguration *pickerConfiguration =
[PHPickerConfiguration alloc] init];
//Swift
var pickerConfiguration = PHPickerConfiguration()
이후, 무슨 Asset을 사용할 건지, 최대 몇장까지 선택할 수 있는 지 등, 사용할 피커에 대한 설정값을 생성한 PHPickerConfiguration 객체에 붙이면 됩니다.
예를 들어, 회사에서는 최대 2장의 사진을 업로드할 수 있고, 선택된 사진의 순서가 보장 되어야하고, 동영상이 아닌 이미지만 업로드 가능하게끔 요청이 들어왔는데, 아래와 같이 PickerConfiguration 객체에 값을 부여할 수 있습니다.
//Objective C
[pickerConfiguation setSelectionLimit: 2]; //0으로 설정시, 개수 제한이 없음
[pickerConfiguation setSelection: PHPickerConfigurationSelectionOrdered];
[pickerConfiguation setFilter: [PHPickerFilter imagesFilter]];
//Swift
pickerConfiguration.selectionLimit = 2 //0으로 설정시, 개수 제한이 없음
pickerConfiguration.selection = .ordered
pickerConfiguration.filter = PHPickerFilter.images
//Objective-C
PHPickerViewController *imagePicker =
[[PHPickerViewController alloc] initWithConfiguration:
pickerConfiguration];
//Swift
let imagePicker = PHPickerViewController(configuration: pickerConfiguration)
// Objective-C
// ViewController.h
...
#import <PhotosUI/PhotosUI.h>
@interface ViewController : UIViewController <PHPickerViewControllerDelegate>
...(다른 프로퍼티 및 메소드 정의)
@end
// ViewController.m
//PickerVC에서 이미지들을 선택 완료했을 때 실행되는 Delegate Method
- (void)picker:(nonnull PHPickerViewController *)picker didFinishPicking:(nonnull NSArray<PHPickerResult *> *)results {
}
// Swift
class ViewController: UIViewController, PHPickerViewControllerDelegate {
...
//PickerVC에서 이미지들을 선택 완료했을 때 실행되는 Delegate Method
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
}
// Objective C
[imagePicker setDelegate: self];
[self presentViewController: imagePicker animated: true completion: nil];
// Swift
imagePicker.delegate = self
self.present(imagePicker, animated: true)
UIImagePickerController의 경우, 사진의 접근 권한과 관련하여 Info.plist의 문구 작성 및 권한 확인이 필요했지만, PHPickerViewController의 경우, 공식문서에도 나와있는 것처럼, PHPickerViewController은 앱과의 별개의 프로세스에서 실행되기 때문에 접근 권한 설정이 따로 없다고 명시되어 있습니다.
다만, 제한적인 라이브러리 사용 등에는 접근 권한에 대해 설정이 필요합니다. 해당 내용은 이 포스트에서 따로 다루진 않고, 추후에 다룰 예정입니다. 접근 권한 설정 공식 문서
Picker를 설정했을 때, 분명히 선택했었던 사진들에 대한 순서가 있도록 하였습니다.
다만, 이미지의 크기가 아무래도 천차만별이다보니, 사진을 선택한 순서대로 서버에 올라가야하는데, 피커에서 UIImage 타입의 이미지로 먼저 컨버팅이 완료된 사진부터 올라가는 상황이 발생하여, 이를 해결하기 위해 Continuation 이라는 개념을 도입하기로 결정하였습니다.
이번 포스팅에서는 간단하게 기존에 활용하였던 ELCImagePickerController 대신 PHPickerViewController이라는 새로운(?) 이미지 피커에 대해서 피커를 띄우는 내용까지 작성을 해보았습니다.
문제점에서 언급되었던 순서에 대한 보장이 되지 않는 점 그리고 Continuation에 대한 이야기는 다음 포스팅에서 이야기하고자 합니다.