(iOS, Swift) Continuations, 그런데PHPickerViewController를 곁들인(1) - PHPickerViewController

GREATHOAXER·2024년 3월 5일

iOS

목록 보기
1/2

0. 들어가며

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

0) 회사에서의 레거시

  • 기존 프로젝트에서는 ELCImagePickerController 이라는 라이선스가 2010년으로 박혀있는 서드파티를 활용하고 있었습니다.
  • 물론, 기능상으로는 문제가 없었지만, Objective-C 가 약 99퍼센트를 차지할정도의 무시무시한 라이브러리였기 때문에, Swift로 기존 Objective-C 레거시 코드를 걷어내고자 하는 목표와는 맞지 않았기 때문에 과감하게 버리고자 하였습니다.

1) 애플에서 기존에 제공주던 이미지 피커

  • 기존에는, UIImagePickerController의 SourceTypephotoLibrary 로 지정하면 우리가 흔히 보는 이미지 피커의 모습을 볼 수 있었습니다.

  • 그러나, 애플에서 지원해주던 이미지 피커의 결정적인 단점이 두가지가 있었는데
    1) 이미지가 여러장 선택이 되지 않는다는 단점과
    2) iOS 15부턴 Deprecated가 된 단점이 있었습니다.

ELCImagePickerController를 쓰라는 답이 달린 것을 보면, 당시 프로덕트를 제작할 때 해당 이미지 피커를 활용하는게 최선의 방법이었던 것 같습니다.

2) 다른 방법은 없는건가

  • UIImagePickerController의 공식문서에서도 언급되었듯이, iOS 14부터 PHPickerViewController을 사용하도록 가이드가 되어 있습니다.

  • PHPickerViewController을 통해 여러장의 이미지 업로드 등, 회사에서 요구하는 사항들을 충족할 수 있을 것 같아, 이번 포스팅에서는 PHPickerViewController에 대해 이야기 해보고자 합니다.

1. PHPickerViewController

  • 공식 문서에서도 확인 가능하듯이, PHPickerViewControllerUIImagePickerController의 대안으로 나온 것입니다.

  • 기존 피커에 비해 많은 개선점들이 있지만, 대표적으론 밑의 두가지가 있습니다.
    1) 파노라마 같은 규모가 크고, 복잡한 Asset의 용이한 처리가 가능
    2) UIImagePickerController에서 사용할 수 없었던 Asset의 선택

1) PHPickerConfiguration

  • 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

2) PHPickerViewController 생성 및 띄우기

  • 앞에서 피커의 설정이 담긴 PickerConfiguration 객체가 있다면, 이제 이를 활용하여 PHImagePickerViewController 객체를 생성하면 됩니다.
//Objective-C
PHPickerViewController *imagePicker =
		[[PHPickerViewController alloc] initWithConfiguration: 
										pickerConfiguration];

//Swift
let imagePicker = PHPickerViewController(configuration: pickerConfiguration)
  • 그 후, 이미지 선택을 한 후 확인을 눌렀을 때 처리할 수 있는 Delegate를 피커를 활용하고 있는 ViewController에 상속을 하고, 이에 대한 메소드들도 정의를 해야합니다.
// 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]) {

}
  • 마지막으로, 위에서 만들어놓은 PHPickerViewController의 객체에 Delegate를 할당한 후, 해당 뷰컨을 present하면 비로소 이미지를 선택할 수 있는 피커가 full modal 형태로 나타나게 됩니다.
// Objective C
[imagePicker setDelegate: self];
[self presentViewController: imagePicker animated: true completion: nil];

// Swift 
imagePicker.delegate = self
self.present(imagePicker, animated: true)
  • 앞서 설정했던대로, 최대 2장의 사진만을 선택할 수 있게끔 되어 있기 때문에, 2장을 선택하면 더이상 선택이 되지 않도록 알아서 Blur처리를 해줍니다.

3) 확인점 및 문제점

  • UIImagePickerController의 경우, 사진의 접근 권한과 관련하여 Info.plist의 문구 작성 및 권한 확인이 필요했지만, PHPickerViewController의 경우, 공식문서에도 나와있는 것처럼, PHPickerViewController은 앱과의 별개의 프로세스에서 실행되기 때문에 접근 권한 설정이 따로 없다고 명시되어 있습니다.

  • 다만, 제한적인 라이브러리 사용 등에는 접근 권한에 대해 설정이 필요합니다. 해당 내용은 이 포스트에서 따로 다루진 않고, 추후에 다룰 예정입니다. 접근 권한 설정 공식 문서

  • Picker를 설정했을 때, 분명히 선택했었던 사진들에 대한 순서가 있도록 하였습니다.

  • 다만, 이미지의 크기가 아무래도 천차만별이다보니, 사진을 선택한 순서대로 서버에 올라가야하는데, 피커에서 UIImage 타입의 이미지로 먼저 컨버팅이 완료된 사진부터 올라가는 상황이 발생하여, 이를 해결하기 위해 Continuation 이라는 개념을 도입하기로 결정하였습니다.

2. 다음 포스팅에서는...

  • 이번 포스팅에서는 간단하게 기존에 활용하였던 ELCImagePickerController 대신 PHPickerViewController이라는 새로운(?) 이미지 피커에 대해서 피커를 띄우는 내용까지 작성을 해보았습니다.

  • 문제점에서 언급되었던 순서에 대한 보장이 되지 않는 점 그리고 Continuation에 대한 이야기는 다음 포스팅에서 이야기하고자 합니다.

profile
Lowest to highest

0개의 댓글