iOS/SwiftUI

PhotoPicker

Hamp 2025. 11. 2. 14:22
반응형

📷 PhotoPicker

 

🧩 역할

SwiftUI에서 시스템 갤러리를 쉽게 띄울수 있게 제공되는 뷰

 

🧱 구조

생성자에 쓰이는 파라미터를 살펴보자.

 

  • selection:
    • Binding<PhotosPickerItem?> 또는 Binding<[PhotosPickerItem]>
    • 갤러리에서 선택한 결과를 바인딩하는 파라미터
  • maxSelectionCount
    • Int?
    • 한번에 고를 수 있는 최대 항목 수, nil = 무제한
  • selectionBehavior
    • PhotosPickerSelectionBehavior
    • 선택 처리에 대한 행동
Behavior 순서 보존 여부연속 선택 제약   여부설명
.default 시스템 기본. 순서 관계 없음, 자유롭게 선택/해제 가능
.ordered 사용자가 선택한 순서를 유지. “1, 2, 3…” 번호가 붙음
.continuous 연속된 구간만 선택 가능. 떨어진 항목끼리는 동시에 선택 불가
.continuousAndOrdered 연속 선택만 허용하면서, 그 선택 순서를 유지
  • matching
    • PHPickerFilter 또는 PHPickerFilter.any(0f: [...])
    • 보여줄 미디어 타입을 제어
  • preferredItemEncoding
    • PhotosPickerItem.EncodingDisambiguationPolicy
    • 선택한 미디어 데이터를 전달할 떄, 어떤 인코딩이된 상태로 전달될 지를 결정
EncodingDisambiguationPolicy 의미 장점  단점
.automatic (기본값) 시스템이 가장 적절한 형식 결저정 무난함  
.current 현재 인코딩 그대로 사용 원본 품질 유지 앱이 해당 포맷을 처리할 수 있어야함
.compatible 가장 호환성이 높은 형식 대부분의 앱에서 별도 처리 없이 바로 사용 변환 과정에서 품질 손실 발생 가능

 

  • photoLibrary
    • PhotoLibrary
    • 어느 PhotoLibrary 인스턴스에서 피커를 열지 지정, 보통 .shared()

 

🤖 사용 예시

 

실제 파라미터 내용들이 파악됐다면, 넣어주는거는 어렵지 않으므로 대충 사용하는 형태만 살펴보자.

 

viewModifier로도 똑같이 제공된다.

 

이 때는 isPresented 플래그 변수를 사용해, 열리고 닫힘을 컨트롤

VStack {
  PhotosPicker(selection: .constant(nil)) {
    Text("Hello")
  }
}

// 또는

VStack {
  Text("Hello").onTapGesture {
    trigger.toggle()
  }
}
.photosPicker(isPresented: $trigger, selection: .constant(nil))

 


🖨️ 가져온 데이터를 UIImage로 변환

loadTransferable함수를 이용하여, Transferable를 채택한 객체, 여기선 Data로 전환할 수 있음

enum PhotosPickerItemTransferError: Error {
  case failedToLoadData
  case missingSelf
}

final class PhotosPickerItemTransfer {
  func transform(_ items: [PhotosPickerItem]) async throws -> [UIImage] {
    try await withThrowingTaskGroup(of: (Int, Data).self) { group in
      for (index, item) in items.enumerated() {
        group.addTask { [weak self] in
          // self가 이미 해제된 경우 작업을 취소하기 위해 에러 반환
          guard let self
          else {
            throw PhotosPickerItemTransferError.missingSelf
          }
          let data = try await self.transform(from: item)
          return (index, data)
        }
      }

      var results: [(Int, Data)] = []

      for try await result in group {
        results.append(result)
      }
      return results.sorted { $0.0 < $1.0 }.compactMap { UIImage(data: $0.1) }
    }
  }

  private func transform(from item: PhotosPickerItem) async throws(PhotosPickerItemTransferError) -> Data {
    guard let data = try? await item.loadTransferable(type: Data.self)
    else {
      throw PhotosPickerItemTransferError.failedToLoadData
    }

    return data
  }
}

출처

https://developer.apple.com/documentation/photosui/photospicker/init%28selection%3Amatching%3Apreferreditemencoding%3Aphotolibrary%3Alabel%3A%29

 

init(selection:matching:preferredItemEncoding:photoLibrary:label:) | Apple Developer Documentation

Creates a picker that selects an item from the photo library you specify and optionally configures the types of items to show, item encoding, and label behavior.

developer.apple.com

 

반응형