PhotoKit
Build media selection, camera capture, photo library queries, and image caching workflows with PhotosUI (PhotosPicker), PhotoKit (PHPhotoLibrary), and AVFoundation. Targets Swift 6.3 / iOS 26+.
Contents
Picker Selection Strategy
| Approach |
UI Framework |
Permissions Needed |
Use Case |
PhotosPicker |
SwiftUI |
None (runs out-of-process) |
User selects photos/videos for import |
PHPickerViewController |
UIKit |
None (runs out-of-process) |
UIKit equivalent of PhotosPicker |
PHPhotoLibrary |
Direct API |
NSPhotoLibraryUsageDescription |
Custom gallery, background sync, asset deletion |
AVCaptureSession |
Custom UI |
NSCameraUsageDescription |
Real-time camera viewfinder, photo/video capture |
Prefer PhotosPicker for standard media selection. It preserves user privacy and eliminates permission friction.
Privacy and Permissions
When accessing PHPhotoLibrary directly, request authorization and handle .limited access:
let status = await PHPhotoLibrary.requestAuthorization(for: .readWrite)
switch status {
case .authorized:
// Full photo library access granted
case .limited:
// User selected specific photos (present PHPhotoLibrary.shared().presentLimitedLibraryPicker)
case .denied, .restricted:
// Direct user to Settings
case .notDetermined:
break
@unknown default:
break
}
Include NSPhotoLibraryUsageDescription (read/write) or NSPhotoLibraryAddUsageDescription (write-only save) in Info.plist.
Image Loading and Caching
Use PHCachingImageManager for fast grid thumbnail generation:
- Prepare caching: Call
startCachingImages(for:targetSize:contentMode:options:) when scrolling into view.
- Reuse options: Use
PHImageRequestOptions with deliveryMode = .opportunistic for quick thumbnails followed by high-res data.
- Cancel obsolete requests: Cancel pending request IDs when cells scroll out of viewport.
Camera Capture Boundaries
For custom camera viewfinders using AVCaptureSession:
- Configure sessions on a dedicated serial background queue, never on
@MainActor.
- Balance every transaction with
session.beginConfiguration() and defer { session.commitConfiguration() }.
- Embed viewfinders in SwiftUI using
UIViewRepresentable backed by AVCaptureVideoPreviewLayer.
Route by Task
- For SwiftUI
PhotosPicker single/multi-selection and media filtering recipes, read PhotosPicker Recipes.
- For complete camera controllers, photo capture, video recording, and barcode scanning, read Camera Capture Patterns.
- For asset fetching, thumbnail caching with
PHCachingImageManager, and memory management, read Image Loading and Caching. For format conversion and compression, read Image Formats and Compression.
- For video playback, custom player UI, and AVPlayer integration, read AV Playback Reference.
Common Mistakes
- Requesting full photo library permissions when
PhotosPicker would suffice without any permissions.
- Hardcoding
.highQualityFormat on PHImageRequestOptions for fast-scrolling grids, causing dropped frames.
- Running
AVCaptureSession.startRunning() or configuration changes on @MainActor.
- Forgetting to handle
.limited photo library access on iOS 14+.
- Loading full-resolution
UIImage into memory for multiple items simultaneously without downsampling.
Review Checklist
References
- PhotoKit patterns and picker recipes
- Camera capture and AVCaptureSession reference
- Image loading, caching, and downsampling
- Image formats and compression
- AV Playback reference
- PhotoKit documentation
- PhotosUI documentation
1---2name: photokit3description: Builds or reviews photo-library picking, image loading, camera capture, and video recording with PhotoKit, PhotosPicker/PHPicker, and AVFoundation. Use for photo or camera permissions, media selection, capture sessions, library changes, caching, or media export.4---56# PhotoKit78Build media selection, camera capture, photo library queries, and image caching workflows with `PhotosUI` (`PhotosPicker`), `PhotoKit` (`PHPhotoLibrary`), and `AVFoundation`. Targets Swift 6.3 / iOS 26+.910## Contents1112- [Picker Selection Strategy](#picker-selection-strategy)13- [Privacy and Permissions](#privacy-and-permissions)14- [Image Loading and Caching](#image-loading-and-caching)15- [Camera Capture Boundaries](#camera-capture-boundaries)16- [Route by Task](#route-by-task)17- [Common Mistakes](#common-mistakes)18- [Review Checklist](#review-checklist)19- [References](#references)2021## Picker Selection Strategy2223| Approach | UI Framework | Permissions Needed | Use Case |24|---|---|---|---|25| `PhotosPicker` | SwiftUI | **None** (runs out-of-process) | User selects photos/videos for import |26| `PHPickerViewController` | UIKit | **None** (runs out-of-process) | UIKit equivalent of PhotosPicker |27| `PHPhotoLibrary` | Direct API | `NSPhotoLibraryUsageDescription` | Custom gallery, background sync, asset deletion |28| `AVCaptureSession` | Custom UI | `NSCameraUsageDescription` | Real-time camera viewfinder, photo/video capture |2930Prefer `PhotosPicker` for standard media selection. It preserves user privacy and eliminates permission friction.3132## Privacy and Permissions3334When accessing `PHPhotoLibrary` directly, request authorization and handle `.limited` access:3536```swift37let status = await PHPhotoLibrary.requestAuthorization(for: .readWrite)38switch status {39case .authorized:40 // Full photo library access granted41case .limited:42 // User selected specific photos (present PHPhotoLibrary.shared().presentLimitedLibraryPicker)43case .denied, .restricted:44 // Direct user to Settings45case .notDetermined:46 break47@unknown default:48 break49}50```5152Include `NSPhotoLibraryUsageDescription` (read/write) or `NSPhotoLibraryAddUsageDescription` (write-only save) in `Info.plist`.5354## Image Loading and Caching5556Use `PHCachingImageManager` for fast grid thumbnail generation:571. **Prepare caching**: Call `startCachingImages(for:targetSize:contentMode:options:)` when scrolling into view.582. **Reuse options**: Use `PHImageRequestOptions` with `deliveryMode = .opportunistic` for quick thumbnails followed by high-res data.593. **Cancel obsolete requests**: Cancel pending request IDs when cells scroll out of viewport.6061## Camera Capture Boundaries6263For custom camera viewfinders using `AVCaptureSession`:64- Configure sessions on a dedicated serial background queue, never on `@MainActor`.65- Balance every transaction with `session.beginConfiguration()` and `defer { session.commitConfiguration() }`.66- Embed viewfinders in SwiftUI using `UIViewRepresentable` backed by `AVCaptureVideoPreviewLayer`.6768## Route by Task6970- For SwiftUI `PhotosPicker` single/multi-selection and media filtering recipes, read [PhotosPicker Recipes](references/photokit-patterns.md).71- For complete camera controllers, photo capture, video recording, and barcode scanning, read [Camera Capture Patterns](references/camera-capture.md).72- For asset fetching, thumbnail caching with `PHCachingImageManager`, and memory management, read [Image Loading and Caching](references/image-loading-caching.md). For format conversion and compression, read [Image Formats and Compression](references/image-formats-compression.md).73- For video playback, custom player UI, and AVPlayer integration, read [AV Playback Reference](references/av-playback.md).7475## Common Mistakes7677- Requesting full photo library permissions when `PhotosPicker` would suffice without any permissions.78- Hardcoding `.highQualityFormat` on `PHImageRequestOptions` for fast-scrolling grids, causing dropped frames.79- Running `AVCaptureSession.startRunning()` or configuration changes on `@MainActor`.80- Forgetting to handle `.limited` photo library access on iOS 14+.81- Loading full-resolution `UIImage` into memory for multiple items simultaneously without downsampling.8283## Review Checklist8485- [ ] `PhotosPicker` preferred over custom library enumeration where appropriate86- [ ] `NSPhotoLibraryUsageDescription` provided when using `PHPhotoLibrary`87- [ ] `NSCameraUsageDescription` provided when using `AVCaptureSession`88- [ ] `.limited` photo library authorization handled gracefully89- [ ] `PHCachingImageManager` used with preheating for asset collections90- [ ] `AVCaptureSession` configured and started on a serial background queue91- [ ] Photo picker item loading handles cancellation and errors asynchronously92- [ ] Image assets downsampled to target display size to prevent memory spikes9394## References9596- [PhotoKit patterns and picker recipes](references/photokit-patterns.md)97- [Camera capture and AVCaptureSession reference](references/camera-capture.md)98- [Image loading, caching, and downsampling](references/image-loading-caching.md)99- [Image formats and compression](references/image-formats-compression.md)100- [AV Playback reference](references/av-playback.md)101- [PhotoKit documentation](https://sosumi.ai/documentation/photokit)102- [PhotosUI documentation](https://sosumi.ai/documentation/photosui)