스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
Photos 선택기의 새로운 기능
PHPicker를 통해 앱과 시스템 사진 라이브러리를 간단하고 안전하게 통합할 수 있습니다. SwiftUI 및 Transferable을 통해 iOS, iPadOS, macOS 및 watchOS 전반에서 통합을 제공하는 방법을 알아보세요. 또한 AppKit 및 NSOpenPanel을 사용하여 Mac의 Photos 선택기를 macOS 앱에 제공하는 방법을 보여드립니다. Photos 선택기에 대해 자세히 알아보려면 WWDC21의 ‘Improve access to Photos in your app(앱에서 Photos 액세스 향상)'을 시청하시기 바랍니다.
리소스
관련 비디오
WWDC23
WWDC22
WWDC21
WWDC20
-
다운로드
♪ 잔잔한 힙합 연주 음악 ♪ ♪ 안녕하세요, 저는 Justin입니다 Photos 팀의 엔지니어예요 오늘 제가 설명하고 싶은 건 시스템 Photos 피커에 우리가 만든 개선 사항들입니다 시스템 Photos 피커는 대부분의 앱이 iOS에서 사진과 영상에 접근하기 위한 최고의 도구입니다 피커는 프로세스 밖에서 돌아가서 여러분의 앱은 그걸 사용하기 위해 라이브러리 접근을 요청할 필요가 없습니다 거기에는 직관적인 UI와 사용하기 쉬운 API가 있습니다 PHPicker API가 낯선 분들은 그걸 상세하게 설명했던 예전 WWDC 세션들을 시청하시면 됩니다 오늘 세션에서는 우리가 피커에 추가한 새 기능들에 대한 개요로 시작하겠습니다 그런 다음 피커가 현재 지원하는 추가 플랫폼과 프레임워크에 관해 얘기해보겠습니다 좋습니다, 들어가보죠 피커는 도입 때부터 이미지, 영상 Live Photo의 필터링을 지원합니다 하지만 우린 여러분의 앱 중 일부에 다른 요건이 있을 수 있다는 걸 압니다 예를 들어 스크린샷 봉합 앱에선 피커에 있는 스크린샷만 보여주길 원합니다 올해 우리가 추가한 새로운 스크린샷 필터로 이제 그게 가능합니다 스크린샷 외에도 우린 다른 자산 타입들도 추가했습니다 화면 녹화와 슬로 모션 비디오처럼요 PHAsset.playbackStyle를 써서 새 필터를 만드는 방법도 있습니다 Cinematic 영상과 깊이 효과 사진과 파열을 제외한 새 필터들 전부가 백포팅이 됩니다 여러분의 앱이 iOS 15을 목표로 한다면 iOS 16 SDK로 컴파일링을 하는 한 그것들을 쓸 수 있습니다 복합 필터의 경우 기존의 'any' 외에도 이제는 'all'과 'not'도 쓸 수 있습니다 그것들도 iOS 15로 백포팅이 됩니다 코드 사례들을 살펴보겠습니다 영상과 Live Photo를 보여주려면 그걸 'any'와 결합하면 됩니다 아니면 여러분은 스크린샷만 보여주고 싶을 수 있습니다 스크린샷 없이 모든 이미지를 보여주려면 여러분은 'all'과 'not'을 써서 이미지와 스크린샷 필터를 결합할 수 있습니다 그리고 마지막 사례는 여러분이 iOS 16을 목표로 한다면 .cinematicVideos filter를 사용할 수 있다는 겁니다 다음으로 박형 피커와 관련된 개선 사항들을 설명하겠습니다 iOS 15에선 UIKit의 새로운 UISheetPresentationController API를 써서 박형 모드의 피커를 제시할 수 있습니다 그건 많은 경우에 이미 효과가 참 좋습니다 그런데 여러분 중 몇몇은 맞춤형 UI를 시행해서 선택된 자산들을 조절하고 그 변화들이 피커에 다시 반영되길 원할 수 있습니다 iOS 16에서 여러분은 자산 식별자를 써서 자산 선택을 해제할 수 있습니다 여기에서 보이듯 deselectAssets가 호출된 후 두 번째 사진은 피커에서 더 이상 선택되지 않습니다 moveAsset 기법을 호출해서 자산을 재정리할 수도 있습니다 이제 우린 새로운 피커 기능들 모두에 익숙해졌으니 플랫폼 지원 얘기를 해보죠 현재 시스템 Photos 피커는 iOS와 iPadOS 앱에서만 사용될 수 있습니다 올해 우린 Photos 피커에 두 가지 플랫폼을 추가합니다 macOS와 watchOS입니다 iPadOS 피커도 iPad만을 위한 새 디자인으로 업데이트됩니다 새로운 iPad UI를 먼저 살펴봅시다 피커에는 이제 사이드바가 생겼는데 이는 비교적 큰 iPad 디스플레이를 활용합니다 사이드바는 서로 다른 모음들 사이를 더 빨리 돌아다닐 수 있게 해줍니다 그런데 Split Screen 모드에서처럼 공간이 부족하면 기존의 소형 피커 UI로 돌아갑니다 다음은 macOS입니다 macOS 피커에도 Mac 스타일의 컨트롤이 있는 사이드바가 있습니다 그리고 iOS picker처럼 그건 다중 선택과 격자에서 유동적 주밍을 지원하고 강력한 검색 기능이 있는데 그건 여러분이 사람, 장소 등 많은 걸 검색할 수 있게 해줍니다 새 피커 UI는 NSOpenPanel에서도 이용 가능합니다 그걸 써서 시스템 사진 라이브러리에서 자산을 고를 수 있고, 처음으로 iCloud Photos에 저장된 자산들을 포함시킵니다 여러분의 앱에 새로운 UI는 무료로 주어집니다 채택 작업은 전혀 할 필요 없이 말이죠 NSOpenPanel 피커에선 끌어 놓기가 지원됩니다 또한 iOS, iPadOS, macOS의 표준형 피커에서도 지원됩니다 여러분의 앱이 이미지나 영상 몇 개만 선택해야 한다면 여러분에겐 NSOpenPanel API만 필요할 수 있습니다 그런데 명심할 건 사진 라이브러리에서 선택된 파일들이 시스템에 의해 언제든 삭제될 수 있다는 점입니다 그것들을 장기적으로 이용할 수 있으려면 그걸 여러분의 앱이 관리하는 위치에 복사해야 합니다 미디어 중심의 macOS 앱의 경우 최고의 사용자 체험을 위해 여러분이 기본 설정을 새 Photos 피커로 하길 권합니다 그래도 여러분의 앱은 파일 시스템에서 자산을 선택할 대안적인 방식을 제공할 겁니다 NSOpenPanel API를 사용해서요 때론 여러분의 고객들이 사진 라이브러리 밖에서 자산을 선택하길 원할 수 있습니다 마지막이지만 중요한 watchOS 얘기를 해봅시다 최초로 여러분은 새로운 API를 써서 Watch에 저장된 이미지에 접근할 수 있습니다 watchOS 피커에서도 프로세스가 바닥이 납니다 iOS와 macOS 피커처럼요 그러니 그걸 쓰려고 라이브러리 권한을 요청할 필요가 없습니다 그것의 UI는 iOS 피커와 유사하지만 더 작은 화면에 최적화되어 있습니다 여러분은 사진을 격자에서 혹은 모음별로 둘러볼 수 있습니다 여러분은 피커가 선택 순서를 보여주게 설정할 수 있으며 선택 한계도 명시할 수 있습니다 하지만 iOS나 macOS와 다르게 watchOS 피커에는 이미지만 표시됩니다 기기에 있는 이미지가 500개를 초과하면 가장 최근의 500개만 보입니다 여러분은 궁금할 수 있죠 'PHPickerViewController는 UIKit를 기반으로 해요' '그걸 어떻게 제 macOS이나 watchOS 앱에 쓸 수 있죠?' 여러분이 추측했을 수도 있는데 새 피커 API는 이제 AppKit와 SwiftUI에서 이용 가능합니다 AppKit API를 먼저 살펴보죠 사실 그건 UIKit API와 아주 비슷합니다 여러분은 동일한 PHPickerConfiguration 타입과 그 속성에 접근할 수 있습니다 작은 차이만 있을 뿐이죠 PHPickerViewController는 AppKit 앱을 위한 NSViewController 서브클래스입니다 AppKit 기반의 PHPicker의 도입으로 이젠 레거시 미디어 라이브러리 브라우저와 결별할 때입니다 PHPicker는 훨씬 더 강력합니다 UIKit와 AppKit 앱 작업을 동시에 한다면 그게 유지하기에도 더 쉽습니다 마지막으로 SwiftUI API 얘기를 할 시간입니다
세션 시작에서 여러분이 봤던 iOS 피커가 기억나나요? 그건 SwiftUI code 몇 줄만으로 제시될 수 있습니다 더욱 중요한 점은 SwiftUI PhotosPicker API에 여러분이 접근할 수 있다는 겁니다 피커가 지원되는 모든 플랫폼에서요 iOS, iPadOS, macOS watchOS에서죠 피커는 최고의 레이아웃을 자동으로 선택합니다 플랫폼과 여러분 앱의 설정과 이용 가능한 화면 공간에 따라서요 여러분은 피커 UI가 뭐가 돼야 할지 걱정할 필요가 없으니 앱을 개선하는 작업에 집중할 수 있습니다
시연을 통해 새로운 API를 자세히 살펴보기 전에 선택된 사진과 영상을 로딩하는 방법을 먼저 설명하는 게 좋겠습니다 SwiftUI 바인딩을 통해 여러분이 받는 선택 결과에는 플레이스홀더 객체들만 들어 있습니다 여러분은 실제 자산 데이터를 언제든 로딩해야 합니다 명심할 점은 일부 자산 데이터가 곧바로 로딩되지 않는다는 겁니다 오류를 접하게 되면 로드 연산도 실패할 수 있습니다 예를 들어 피커가 iCloud Photos에서 데이터를 다운받으려 했지만 기기가 인터넷에 연결되지 않았을 때 말이죠 영상 같은 큰 파일들은 다운받는 데 오래 걸릴 수 있어서 여러분이 아이템별 인라인 로딩 UI를 보여주시길 권합니다 로딩 인디케이터를 막지 말고요 PhotosPicker는 Transferable을 사용합니다 그건 앱과 확장 프로그램 사이에서 데이터 이전을 위한 새로운 SwiftUI입니다 Transferable을 통해 직접 SwiftUI Image를 로딩할 수 있는데 고급 이용 사례들의 경우 Transferable 프로토콜을 준수하는 여러분만의 모델 객체를 정의해서 로딩하고 싶은 데이터 타입을 완전히 제어해야 합니다 Transferable에 관한 자세한 정보를 원하면 'Meet Transferable' 세션을 확인해보시면 됩니다 여러분의 앱이 동시에 여러 항목이나 영상처럼 큰 자산을 처리해야 한다면 메모리에 모든 걸 동시에 로딩하는 건 적절치 않을 수 있습니다 메모리 사용량을 줄이기 위해 FileTransferRepresentation을 써서, 선택된 자산들을 파일로 로딩할 수 있습니다 자산을 파일로 로딩할 때 명심할 점은 여러분의 앱이 그 수명 주기를 관리하는 걸 담당하고 있다는 점입니다 파일을 받으면 앱 디렉토리에 반드시 복사해 놓고 더 이상 필요하지 않으면 삭제해야 합니다 좋아요, 이제 시연 시간입니다 전 이 데모 앱을 이미 준비해놨는데요 계정 프로필 페이지를 보여주고 있습니다 현재 프로필 이미지는 플레이스홀더 아이콘입니다 우린 PhotosPicker API를 써서 편집 버튼을 추가하여 프로필 이미지를 바꾸고 싶습니다 프로필 이미지 뷰는 뷰 모델에서 정의된 이미지 상태에 이미 반응할 수 있어서 피커 선택을 받으면 우린 이미지 상태를 업데이트하기만 하면 됩니다 먼저 우리의 뷰 모델로 가서 imageSelection 속성을 새롭게 추가해보죠 그건 선택 바인딩으로 PhotosPicker API에 전달될 겁니다 이제 우린 프로필 이미지 뷰로 돌아가서 피커를 띄워주는 오버레이 버튼을 추가합니다
좋아요, 잠시 멈추고 방금 우리가 추가한 코드를 살펴봅시다 우린 PhotosPicker 뷰를 추가했고 그것에 방금 정의한 선택 바인딩을 부여했고 이미지만 보여주도록 그걸 설정했습니다 PhotosPicker의 레이블은 원 배경이 있는 연필 도안입니다 우린 구축하고 돌려서 지금까지 우리가 해온 걸 볼 수 있습니다 저는 편집 버튼을 두드려서 피커를 화면에 띄웁니다 이미지를 두드리면 피커는 자동으로 닫히지만 프로필 이미지는 업데이트되지 않습니다 왜 그럴까요? 우린 여전히 이미지 선택을 이미지 상태에 연결시켜야 합니다 그럼 그렇게 해보죠 우린 뷰 모델로 돌아가서 이미지 선택 설정 해제에 반응할 수 있습니다 이미지 선택이 nil이면 이미지 상태를 empty로 정합니다 그렇지 않다면 이미지를 로딩하기 시작합니다 컴파일러 오류가 보이는데요 우리가 loadTransferable 기법을 아직 실행하지 않았기 때문입니다 오류를 고쳐보죠
실행은 아주 간단합니다 완료 핸들러와 업데이트 이미지 상태에 반응하기만 하면 됩니다 그 요청이 아직도 가장 최근 것이라면요 이제 구축하고 돌려서 작동하는 모습을 봅시다 저는 편집 버튼을 두드려서 이미지를 선택할 수 있습니다 멋지네요, 예상한 대로 작동됩니다 사실 이 프로젝트는 macOS에서도 돌아갈 수 있게 구성됐습니다 방금 추가한 코드가 macOS에서도 자동으로 작동할까요? 구축하고 돌려서 알아봅시다 컴파일링이 됩니다 저는 피커를 열어서 이미지를 선택할 수 있고 그건 앱에 반영됩니다 여기까지 시연이었습니다 여러분은 iOS와 macOS에서의 시연을 보셨습니다만 동일한 코드가 watchOS에서도 작동됩니다 다만 염두에 둬야 할 게 몇 가지 있습니다
watchOS 피커는 간단한 흐름과 짧은 상호 작용을 위해 디자인되었습니다 이미지들은 기기 크기에 따라 스케일링됩니다 그것들은 대체로 페어링된 iPhone에서 동기화됩니다 하지만 Family Setup은 자기 소유의 iPhone이 없는 여러분의 가족 구성원이 Apple Watch의 기능과 혜택을 즐길 수 있게 해줍니다 기기가 Family Setup 모드에 있으면 피커를 써서 Cloud Photos에 있는 가장 최근 이미지 1000개가 선택될 수 있습니다 피커는 인터넷에서 이미지들을 다운받아야 할 수도 있습니다 그런 경우라면 닫히기 전에 피커에 로딩 UI가 보일 겁니다
끝내기 전에 말씀드리고 싶은 건 시스템 Photos 피커가 대부분의 앱에서 사진과 영상에 접근하는 방법 중 최고가 되는 데 우리가 전념한다는 겁니다 여러분이 여전히 맞춤형 피커를 쓰고 있다면 그걸로 바꾸시길 강력하게 권합니다 감사합니다 WWDC 많이 즐겨주세요 ♪
-
-
0:01 - PHPicker Example (UIKit)
var configuration = PHPickerConfiguration() configuration.filter = .images configuration.selection = .ordered configuration.selectionLimit = 10 let picker = PHPickerViewController(configuration: configuration)
-
0:02 - PHPickerFilter
var configuration = PHPickerConfiguration() // iOS 15 // Shows videos and Live Photos configuration.filter = .any(of: [.videos, .livePhotos]) // New: iOS 15 // Shows screenshots only configuration.filter = .screenshots // New: iOS 15 // Shows images excluding screenshots configuration.filter = .all(of: [.images, .not(.screenshots)]) // New: iOS 16 // Shows cinematic videos configuration.filter = .cinematicVideos
-
0:03 - PHPicker Example (AppKit)
var configuration = PHPickerConfiguration() configuration.filter = .images configuration.selectionLimit = 10 let picker = PHPickerViewController(configuration: configuration)
-
0:04 - PhotosPicker Example (SwiftUI)
struct ContentView: View { @Binding selection: [PhotosPickerItem] var body: some View { PhotosPicker( selection: $selection, matching: .images ) { Text("Select Photos") } } }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.