
Photosui
- 220 installs
- 297 repo stars
- Updated August 4, 2026
- vabole/apple-skills
Integrate PHPicker and PhotosUI pickers for camera roll access, limited library selection, and privacy-safe media import in iOS apps.
About
photosui skill in vabole/apple-skills guides PhotosUI and PHPicker integration: configure pickers, handle limited library permissions, process selected assets, and present results in SwiftUI with Apple-recommended privacy-safe media import flows.
- Configures PHPicker with filter and selection limits
- Handles limited photo library and permission prompts
- Maps picker results to SwiftUI state and models
- Supports single and multi-select media workflows
- Follows privacy-preserving Apple picker patterns
Photosui by the numbers
- 220 all-time installs (skills.sh)
- +4 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #416 of 1,039 Mobile Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/vabole/apple-skills --skill photosuiAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 220 |
|---|---|
| repo stars | ★ 297 |
| Last updated | August 4, 2026 |
| Repository | vabole/apple-skills ↗ |
What it does
Integrate PHPicker and PhotosUI pickers for camera roll access, limited library selection, and privacy-safe media import in iOS apps.
Files
PhotosUI Documentation
Search these docs to answer questions about photo picker APIs.
Return Format
Always include: 1. Summary - Answer the question concisely 2. File paths - List relevant files for full details
Files
photosui-index.md- Framework overview, Live Photo viewsphotospicker.md- SwiftUI PhotosPicker for selecting photos
Navigation: PhotosUI
Structure
PhotosPicker
Available on: iOS 16.0+, iPadOS 16.0+, Mac Catalyst, macOS 13.0+, visionOS, watchOS 9.0+
A view that displays a Photos picker for choosing assets from the photo library.
@MainActor @preconcurrency struct PhotosPicker<Label> where Label : ViewOverview
Use the Photos picker view to browse and select images and videos from the photo library. The view contains methods for single selection and multiple selection. For example, the following code displays a button that — when pressed — shows a picker in multiple selection mode.
import SwiftUI
import PhotosUI
struct PhotosSelector: View {
@State var selectedItems: [PhotosPickerItem] = []
var body: some View {
PhotosPicker(selection: $selectedItems,
matching: .images) {
Text("Select Multiple Photos")
}
}
}When displaying the picker, you can use PHPickerFilter options to customize what it displays. For example, the following code displays images and excludes screenshots.
PhotosPicker(selection: $selectedItems,
matching: .any(of: [.images, .not(.screenshots)])) {
Text("Select Photos")
}The selection results you get are placeholder objects. A PhotosPickerItem conforms to Transferable, and allows you to load a representation you request. To load a SwiftUI Image and track progress, use loadTransferable(type:completionHandler:)).
func loadTransferable(from imageSelection: PhotosPickerItem) -> Progress {
return imageSelection.loadTransferable(type: Image.self) { result in
DispatchQueue.main.async {
guard imageSelection == self.imageSelection else { return }
switch result {
case .success(let image?):
// Handle the success case with the image.
case .success(nil):
// Handle the success case with an empty value.
case .failure(let error):
// Handle the failure case with the provided error.
}
}
}
}A failure can occur when the system attempts to retrieve the data. For example, if the picker tries to download data from iCloud Photos without a network connection.
Important: Image only supportsPNGfile types through its Transferable conformance, so you need to create a customTransferablemodel to support other image types. See Bringing Photos picker to your SwiftUI app to learn more.
Conforms To
Creating a picker
- init(selection:matching:preferredItemEncoding:label:)) Creates a picker that selects an item and optionally configures the types of items to show, item encoding, and label behavior.
- init(selection:maxSelectionCount:selectionBehavior:matching:preferredItemEncoding:label:)) Creates a picker that selects a collection of items and optionally configures the max selection count, selection behavior, types of items to show, item encoding, and label behavior.
- init(selection:matching:preferredItemEncoding:photoLibrary:label:)) 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.
- init(selection:maxSelectionCount:selectionBehavior:matching:preferredItemEncoding:photoLibrary:label:)) Creates a picker that selects a collection of items from the photo library you specify and optionally configures the max selection count, selection behavior, types of items to show, item encoding, and label behavior.
Creating a picker with a title
- init(_:selection:matching:preferredItemEncoding:)-7jbef) Creates a picker with a title key and selection, and optionally configures the types of items to show and item encoding behavior.
- init(_:selection:matching:preferredItemEncoding:)-48f7l) Creates a picker with a title and selection, and optionally configures the types of items to show and item encoding behavior.
- init(_:selection:maxSelectionCount:selectionBehavior:matching:preferredItemEncoding:)-8ac23) Creates a picker with a title key and selection, and optionally configures the max selection count, selection behavior, types of items to show, item encoding, and label behavior.
- init(_:selection:maxSelectionCount:selectionBehavior:matching:preferredItemEncoding:)-6m11r) Creates a picker with a title and selection, and optionally configures the max selection count, selection behavior, types of items to show, item encoding, and label behavior.
- init(_:selection:matching:preferredItemEncoding:photoLibrary:)-bu7c) Creates a picker with a title key and selection from the photo library you specify, and optionally configures the types of items to show, item encoding, and label behavior.
- init(_:selection:matching:preferredItemEncoding:photoLibrary:)-6bm2n) Creates a picker with a title and selection from the photo library you specify, and optionally configures the types of items to show, item encoding, and label behavior.
- init(_:selection:maxSelectionCount:selectionBehavior:matching:preferredItemEncoding:photoLibrary:)-5tpfd) Creates a picker with a title key and selection from the photo library you specify, and optionally configures the max selection count, selection behavior, types of items to show, item encoding, and label behavior.
- init(_:selection:maxSelectionCount:selectionBehavior:matching:preferredItemEncoding:photoLibrary:)-6fwsc) Creates a picker with a title and selection from the photo library you specify, and optionally configures the max selection count, selection behavior, types of items to show, item encoding, and label behavior.
Photos picker for SwiftUI
- Bringing Photos picker to your SwiftUI app Select media assets by using a Photos picker view that SwiftUI provides.
- Implementing an inline Photos picker Embed a system-provided, half-height Photos picker into your app’s view.
- PhotosPickerItem A type that represents an item you use with a Photos picker.
- PhotosPickerSelectionBehavior A type that describes how the Photos picker handles user selection.
- PhotosPickerStyle
---
Extracted from Apple DocC JSON by apple-skills tooling. This is unofficial content. All documentation belongs to Apple Inc.
Navigation: PhotosUI
Shared photo library
Choosing a Live Photo to Display
Managing Playback
Responding to Playback Events
Responding to Live Photos Playback Events
- func livePhotoView(PHLivePhotoView, canBeginPlaybackWith: PHLivePhotoViewPlaybackStyle) -> Bool)
- func livePhotoView(PHLivePhotoView, willBeginPlaybackWith: PHLivePhotoViewPlaybackStyle))
- func livePhotoView(PHLivePhotoView, didEndPlaybackWith: PHLivePhotoViewPlaybackStyle))
- func livePhotoView(PHLivePhotoView, extraMinimumTouchDurationFor: UITouch, with: PHLivePhotoViewPlaybackStyle) -> TimeInterval)
Manually Playing Live Photo Content
- func startPlayback(with: PHLivePhotoViewPlaybackStyle))
- func stopPlayback())
- func stopPlayback(animated: Bool))
Accessing User Interface Icons for Live Photos
- class func livePhotoBadgeImage(options: PHLivePhotoBadgeOptions) -> UIImage)
- var livePhotoBadgeView: NSView?
Setting the Content Mode
Content Modes
Initializers
Constants
Constants
Initializers
Initializers
Constants
Instance Properties
Photos picker for UIKit, AppKit
Creating a picker
Creating a configuration
Filtering asset types
Creating Filters
- static func playbackStyle(PHAsset.PlaybackStyle) -> PHPickerFilter)
- [static func all(of: [PHPickerFilter]) -> PHPickerFilter](/documentation/photosui/phpickerfilter-swift.struct/all(of:))
- static func not(PHPickerFilter) -> PHPickerFilter)
Getting Filter Types
- static let bursts: PHPickerFilter
- static let cinematicVideos: PHPickerFilter
- static let depthEffectPhotos: PHPickerFilter
- static let images: PHPickerFilter
- static let livePhotos: PHPickerFilter
- static let panoramas: PHPickerFilter
- static let screenRecordings: PHPickerFilter
- static let screenshots: PHPickerFilter
- static let slomoVideos: PHPickerFilter
- static let timelapseVideos: PHPickerFilter
- static let videos: PHPickerFilter
- [static func any(of: [PHPickerFilter]) -> PHPickerFilter](/documentation/photosui/phpickerfilter-swift.struct/any(of:))
Type Properties
Selecting the preferred asset representation
- var preferredAssetRepresentationMode: PHPickerConfiguration.AssetRepresentationMode
- PHPickerConfiguration.AssetRepresentationMode
Constants
Preselecting assets
- [var preselectedAssetIdentifiers: [String]](/documentation/photosui/phpickerconfiguration-swift.struct/preselectedassetidentifiers)
Setting the selection limit
Selection methods
Initializers
Selection methods
Customizing picker appearance and behavior
Laying out photos
Specifying features
- static var collectionNavigation: PHPickerCapabilities
- static var selectionActions: PHPickerCapabilities
- static var search: PHPickerCapabilities
- static var sensitivityAnalysisIntervention: PHPickerCapabilities
- static var stagingArea: PHPickerCapabilities
Creating a capability
Creating an update object
Adjusting selection limits
Adjusting content margins
Managing the configuration
Setting content position and scale
Responding to user selection
Instance Methods
- [func picker(PHPickerViewController, didFinishPicking: [PHPickerResult])](/documentation/photosui/phpickerviewcontrollerdelegate-5yntc/picker(_:didfinishpicking:))
Inspecting the Result
Deselecting assets
- [func deselectAssets(withIdentifiers: [String])](/documentation/photosui/phpickerviewcontroller/deselectassets(withidentifiers:))
Reordering assets
Instance Methods
- [func picker(PHPickerViewController, didFinishPicking: [PHPickerResult])](/documentation/photosui/phpickerviewcontrollerdelegate-5yntc/picker(_:didfinishpicking:))
Creating a configuration
Filtering asset types
Creating Filters
- static func playbackStyle(PHAsset.PlaybackStyle) -> PHPickerFilter)
- [static func all(of: [PHPickerFilter]) -> PHPickerFilter](/documentation/photosui/phpickerfilter-swift.struct/all(of:))
- static func not(PHPickerFilter) -> PHPickerFilter)
Getting Filter Types
- static let bursts: PHPickerFilter
- static let cinematicVideos: PHPickerFilter
- static let depthEffectPhotos: PHPickerFilter
- static let images: PHPickerFilter
- static let livePhotos: PHPickerFilter
- static let panoramas: PHPickerFilter
- static let screenRecordings: PHPickerFilter
- static let screenshots: PHPickerFilter
- static let slomoVideos: PHPickerFilter
- static let timelapseVideos: PHPickerFilter
- static let videos: PHPickerFilter
- [static func any(of: [PHPickerFilter]) -> PHPickerFilter](/documentation/photosui/phpickerfilter-swift.struct/any(of:))
Type Properties
Selecting the preferred asset representation
- var preferredAssetRepresentationMode: PHPickerConfiguration.AssetRepresentationMode
- PHPickerConfiguration.AssetRepresentationMode
Constants
Preselecting assets
- [var preselectedAssetIdentifiers: [String]](/documentation/photosui/phpickerconfiguration-swift.struct/preselectedassetidentifiers)
Setting the selection limit
Selection methods
Initializers
Selection methods
Customizing picker appearance and behavior
Laying out photos
Specifying features
- static var collectionNavigation: PHPickerCapabilities
- static var selectionActions: PHPickerCapabilities
- static var search: PHPickerCapabilities
- static var sensitivityAnalysisIntervention: PHPickerCapabilities
- static var stagingArea: PHPickerCapabilities
Creating a capability
Creating an update object
Adjusting selection limits
Adjusting content margins
Creating Filters
- static func playbackStyle(PHAsset.PlaybackStyle) -> PHPickerFilter)
- [static func all(of: [PHPickerFilter]) -> PHPickerFilter](/documentation/photosui/phpickerfilter-swift.struct/all(of:))
- static func not(PHPickerFilter) -> PHPickerFilter)
Getting Filter Types
- static let bursts: PHPickerFilter
- static let cinematicVideos: PHPickerFilter
- static let depthEffectPhotos: PHPickerFilter
- static let images: PHPickerFilter
- static let livePhotos: PHPickerFilter
- static let panoramas: PHPickerFilter
- static let screenRecordings: PHPickerFilter
- static let screenshots: PHPickerFilter
- static let slomoVideos: PHPickerFilter
- static let timelapseVideos: PHPickerFilter
- static let videos: PHPickerFilter
- [static func any(of: [PHPickerFilter]) -> PHPickerFilter](/documentation/photosui/phpickerfilter-swift.struct/any(of:))
Type Properties
Inspecting the Result
Photos picker for SwiftUI
Creating a picker
- init(selection: Binding<PhotosPickerItem?>, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy, label: () -> Label))
- [init(selection: Binding<[PhotosPickerItem]>, maxSelectionCount: Int?, selectionBehavior: PhotosPickerSelectionBehavior, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy, label: () -> Label)](/documentation/photosui/photospicker/init(selection:maxselectioncount:selectionbehavior:matching:preferreditemencoding:label:))
- init(selection: Binding<PhotosPickerItem?>, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy, photoLibrary: PHPhotoLibrary, label: () -> Label))
- [init(selection: Binding<[PhotosPickerItem]>, maxSelectionCount: Int?, selectionBehavior: PhotosPickerSelectionBehavior, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy, photoLibrary: PHPhotoLibrary, label: () -> Label)](/documentation/photosui/photospicker/init(selection:maxselectioncount:selectionbehavior:matching:preferreditemencoding:photolibrary:label:))
Creating a picker with a title
- init(LocalizedStringKey, selection: Binding<PhotosPickerItem?>, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy)-7jbef)
- init<S>(S, selection: Binding<PhotosPickerItem?>, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy)-48f7l)
- [init(LocalizedStringKey, selection: Binding<[PhotosPickerItem]>, maxSelectionCount: Int?, selectionBehavior: PhotosPickerSelectionBehavior, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy)](/documentation/photosui/photospicker/init(_:selection:maxselectioncount:selectionbehavior:matching:preferreditemencoding:)-8ac23)
- [init<S>(S, selection: Binding<[PhotosPickerItem]>, maxSelectionCount: Int?, selectionBehavior: PhotosPickerSelectionBehavior, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy)](/documentation/photosui/photospicker/init(_:selection:maxselectioncount:selectionbehavior:matching:preferreditemencoding:)-6m11r)
- init(LocalizedStringKey, selection: Binding<PhotosPickerItem?>, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy, photoLibrary: PHPhotoLibrary)-bu7c)
- init<S>(S, selection: Binding<PhotosPickerItem?>, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy, photoLibrary: PHPhotoLibrary)-6bm2n)
- [init(LocalizedStringKey, selection: Binding<[PhotosPickerItem]>, maxSelectionCount: Int?, selectionBehavior: PhotosPickerSelectionBehavior, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy, photoLibrary: PHPhotoLibrary)](/documentation/photosui/photospicker/init(_:selection:maxselectioncount:selectionbehavior:matching:preferreditemencoding:photolibrary:)-5tpfd)
- [init<S>(S, selection: Binding<[PhotosPickerItem]>, maxSelectionCount: Int?, selectionBehavior: PhotosPickerSelectionBehavior, matching: PHPickerFilter?, preferredItemEncoding: PhotosPickerItem.EncodingDisambiguationPolicy, photoLibrary: PHPhotoLibrary)](/documentation/photosui/photospicker/init(_:selection:maxselectioncount:selectionbehavior:matching:preferreditemencoding:photolibrary:)-6fwsc)
Creating a picker item
Inspecting a picker item
- var itemIdentifier: String?
- [var supportedContentTypes: [UTType]](/documentation/photosui/photospickeritem/supportedcontenttypes)
Getting an encoding policy
Getting standard encoding policies
- static let automatic: PhotosPickerItem.EncodingDisambiguationPolicy
- static let current: PhotosPickerItem.EncodingDisambiguationPolicy
- static let compatible: PhotosPickerItem.EncodingDisambiguationPolicy
Loading the provider’s contents
- func loadTransferable<T>(type: T.Type) async throws -> sending T?)
- func loadTransferable<T>(type: T.Type, completionHandler: (Result<T?, any Error>) -> Void) -> Progress)
Getting standard selection behaviors
- static let `default`: PhotosPickerSelectionBehavior
- static let ordered: PhotosPickerSelectionBehavior
Type Properties
- static let continuous: PhotosPickerSelectionBehavior
- static let continuousAndOrdered: PhotosPickerSelectionBehavior
Type Properties
- static let compact: PhotosPickerStyle
- static let inline: PhotosPickerStyle
- static let presentation: PhotosPickerStyle
Live Photos
Photo Editing Extensions
Working with Adjustment Data
Performing an Edit
- func startContentEditing(with: PHContentEditingInput, placeholderImage: UIImage))
- func finishContentEditing(completionHandler: (PHContentEditingOutput?) -> Void))
Canceling an Edit
macOS Photos Project Extensions
Determining Project Type
Initializing a Project Type
Defining a Project Type
- var creationSource: PHProjectInfo.CreationSource
- [var sections: [PHProjectSection]](/documentation/photosui/phprojectinfo/sections)
- PHProjectTypeDescription
Creating a Project Type Description
- convenience init(projectType: PHProjectType, title: String, description: String?, image: NSImage?))
- [init(projectType: PHProjectType, title: String, description: String?, image: NSImage?, subtypeDescriptions: [PHProjectTypeDescription])](/documentation/photosui/phprojecttypedescription/init(projecttype:title:description:image:subtypedescriptions:))
- [init(projectType: PHProjectType, title: String, attributedDescription: NSAttributedString?, image: NSImage?, subtypeDescriptions: [PHProjectTypeDescription])](/documentation/photosui/phprojecttypedescription/init(projecttype:title:attributeddescription:image:subtypedescriptions:))
- init(projectType: PHProjectType, title: String, description: String?, image: NSImage?, canProvideSubtypes: Bool))
- init(projectType: PHProjectType, title: String, attributedDescription: NSAttributedString?, image: NSImage?, canProvideSubtypes: Bool))
Describing a Project Type
- var projectType: PHProjectType
- var localizedTitle: String
- var localizedDescription: String?
- var localizedAttributedDescription: NSAttributedString?
- var image: NSImage?
- [var subtypeDescriptions: [PHProjectTypeDescription]](/documentation/photosui/phprojecttypedescription/subtypedescriptions)
- var canProvideSubtypes: Bool
Providing Required Fields
- [func subtypes(for: PHProjectType) -> [PHProjectTypeDescription]](/documentation/photosui/phprojecttypedescriptiondatasource/subtypes(for:))
- func typeDescription(for: PHProjectType) -> PHProjectTypeDescription?)
- func footerText(forSubtypesOf: PHProjectType) -> NSAttributedString?)
Responding to Removal
Invalidating a Project Type
- func invalidateTypeDescription(for: PHProjectType))
- func invalidateFooterText(forSubtypesOf: PHProjectType))
Project Sources
- case undefined
- case userSelection
- case album
- case memory
- case moment
- case project
- case projectBook
- case projectCalendar
- case projectCard
- case projectPrintOrder
- case projectSlideshow
- case projectExtension
Initializers
Creating a Project from an Apple Print Product
- var brandingEnabled: Bool
- var pageNumbersEnabled: Bool
- var productIdentifier: String?
- var themeIdentifier: String?
Accessing the Project and the Photo Library
Updating Assets
- func showEditor(for: PHAsset))
- func updatedProjectInfo(from: PHProjectInfo?, completion: (PHProjectInfo?) -> Void) -> Progress)
Subclassing Project Elements
Characterizing an Asset Element
- var annotation: String
- var cloudAssetIdentifier: PHCloudIdentifier
- var cropRect: CGRect
- [var regionsOfInterest: [PHProjectRegionOfInterest]](/documentation/photosui/phprojectassetelement/regionsofinterest)
- var horizontallyFlipped: Bool
- var verticallyFlipped: Bool
Describing a Text Element
- var text: String
- var attributedText: NSAttributedString?
- var textElementType: PHProjectTextElement.ElementType
- PHProjectTextElement.ElementType
Types of Text Elements
Initializers
Describing a Journal Entry
Pinpointing the Map
- var mapType: MKMapType
- var centerCoordinate: CLLocationCoordinate2D
- var heading: CLLocationDirection
- var pitch: CGFloat
- var altitude: CLLocationDistance
- [var annotations: [any MKAnnotation]](/documentation/photosui/phprojectmapelement/annotations)
Describing Project Elements
Determining Section Contents
- var title: String
- [var sectionContents: [PHProjectSectionContent]](/documentation/photosui/phprojectsection/sectioncontents)
- PHProjectSectionContent
Determining Content Properties
- [var elements: [PHProjectElement]](/documentation/photosui/phprojectsectioncontent/elements)
- var numberOfColumns: Int
- var aspectRatio: Double
- [var cloudAssetIdentifiers: [PHCloudIdentifier]](/documentation/photosui/phprojectsectioncontent/cloudassetidentifiers)
- var backgroundColor: NSColor?
Defining the Section Type
Section Types
Initializers
Identifying Regions of Interest
Initializing an Identifier
Determining Region Properties
- var rect: CGRect
- var identifier: PHProjectRegionOfInterest.Identifier
- var weight: Double
- var quality: Double
Tracking the Project Extension Life Cycle
- func beginProject(with: PHProjectExtensionContext, projectInfo: PHProjectInfo, completion: ((any Error)?) -> Void))
- func finishProject(completionHandler: () -> Void))
- func resumeProject(with: PHProjectExtensionContext, completion: ((any Error)?) -> Void))
- func typeDescriptionDataSource(for: PHProjectCategory, invalidator: any PHProjectTypeDescriptionInvalidator) -> any PHProjectTypeDescriptionDataSource)
Defining Supported Project Types
- [var supportedProjectTypes: [PHProjectTypeDescription]](/documentation/photosui/phprojectextensioncontroller/supportedprojecttypes)
Creating a Project Category
Designating Type Properties
- static let book: PHProjectCategory
- static let calendar: PHProjectCategory
- static let card: PHProjectCategory
- static let prints: PHProjectCategory
- static let slideshow: PHProjectCategory
- static let wallDecor: PHProjectCategory
- static let other: PHProjectCategory
- static let undefined: PHProjectCategory
---
Extracted from Apple DocC JSON by apple-skills tooling. This is unofficial content. All documentation belongs to Apple Inc.