- Swift 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| PhotoClean | ||
| PhotoClean.xcodeproj | ||
| .gitignore | ||
| README.md | ||
PhotoClean
A small macOS app that helps you find and clear out the videos eating up space in your Photos library. It lists every video sorted by file size, lets you preview them, export the untouched originals, and move the ones you don't want to Recently Deleted.
Features
- Video list — every video in the Photos library in a sortable table (name, size, length, resolution, creation date) with thumbnails, sorted largest-first by default.
- Minimum-length filter — a slider (0–300s) hides short clips; the header shows how many videos match and how much space they take.
- Preview — double-click, press Space/Return, or use the toolbar to play a video in a sheet. Streams from iCloud when the original isn't local.
- Export — writes the original file, byte for byte, to a folder you pick.
Embedded metadata is preserved and the file is named
2023-08-14_15-30-22 IMG_1234.mov, with the creation date also applied to the file itself. Existing files are never overwritten. - Delete — moves the selection to Recently Deleted in Photos (restorable for 30 days). macOS shows its own confirmation before anything changes.
- Length distribution — bar charts showing how videos and storage are spread across length buckets (0–15s through 30m+), over the whole library.
Requirements
- macOS 14.0 or later
- Xcode 16 or later (Swift 5, project format
objectVersion = 70)
Building
Open PhotoClean.xcodeproj in Xcode and run the PhotoClean scheme, or from
the command line:
xcodebuild -project PhotoClean.xcodeproj -scheme PhotoClean -configuration Debug build
On first launch the app asks for read/write access to your Photos library. It needs write access only to move videos to Recently Deleted; without access the app shows an explanatory screen instead of the list.
Project layout
| File | What's in it |
|---|---|
PhotoCleanApp.swift |
App entry point and window sizing |
RootView.swift |
Sidebar navigation, gates on the library's load state |
VideoLibrary.swift |
PHPhotoLibrary access, fetching, deletion, export |
VideoListView.swift |
The table, filter bar, toolbar, delete/export flows |
DistributionView.swift |
Length-bucket charts (Swift Charts) |
VideoPreviewView.swift |
AVPlayer sheet for a single asset |
ThumbnailView.swift |
Lazy thumbnail loading via PHImageManager |
StatusViews.swift |
Loading and permission-denied states |
Formatting.swift |
Shared size/duration/date formatting |
Notes
PHAsset has no public file-size API, so VideoLibrary.fileSize(for:) reads the
undocumented (but long-stable) fileSize value off each PHAssetResource via
KVC, taking the largest video resource and falling back to the sum of whatever
the resources report.