v0.2.0 — Live Photo
Live Photo support. Surfaces both halves of a Live Photo PHAsset as kadr clip types — drop the motion as a `VideoClip` (animated story card / boomerang), drop the still as an `ImageClip`, or use both.
What's new
import Kadr
import KadrPhotos
// Motion half — animated story card
let motion = try await PhotosClipResolver.livePhotoMotion(asset: livePhotoAsset)
let video = Video {
motion
motion.reversed() // boomerang
}
// Still half — explicit Live-Photo guard
let still = try await PhotosClipResolver.livePhotoStill(asset: livePhotoAsset, duration: 3.0)- `PhotosClipResolver.livePhotoMotion(asset:progress:)` — extracts the paired-video resource via `PHAssetResource` + `PHAssetResourceManager.writeData` to a temp `.mov` URL.
- `PhotosClipResolver.livePhotoStill(asset:duration:options:progress:)` — symmetric Live-Photo-guarded wrapper around `image()`. `CMTime` and `TimeInterval` overloads.
- New `PhotosClipError.notALivePhoto` for assets where `mediaSubtypes.contains(.photoLive)` is false.
Compatibility
- Requires kadr ≥ 0.9.2 (unchanged).
- iOS 16+ / macOS 13+ / visionOS 1+. tvOS still excluded.
- Pure additive — every v0.1 call site compiles unchanged.
Tests
Suite: 15 → 21 (+6).
What's next
- v0.3.0 — `PHPickerViewController` SwiftUI wrapper
- v0.4.0 — PHAsset metadata exposure + direct asset → `ImageOverlay` / `StickerOverlay` helpers
Full notes in CHANGELOG.md.