AVCaptureViewModel
is an ObservableObject
with exposed @Published
properties to be used with the provided CameraPreview
(SwiftUI) or CameraPreviewView
(UIKit). It allows you to build a custom interface around them as part of a larger View
or UIViewController
(respectively) for capturing photos and videos.
It can be used to capture photos and videos to be immediately sent to the device's photo library, or you can subscribe to provided @Published
properties to get the captures as they happen.
There is still more work to be done to provide more granular control, but it's already functional as it is.
- Some kind of subscribable publisher (likely a
CurrentValueSubject
) for publishing events (such as photo capture starting/ending, etc) - Exposing more properties for customizability
- Fix existing issues with screen rotation
- Implement @MainActor on
AVCaptureViewModel
and implement removal ofDispatchQueue.main.async { }
- Figure out how to automatically resize
CameraPreviewView
to fit the size of the preview (i.e. when it's in photo mode, it doesn't fill the space) - Add a function for pinch gesture/zoom
COMING SOON
- The framework doesn't currently support a built-in way to keep the screen from rotating while recording a video, as this isn't possible the way it's written. So if your app allows for multiple orientations, you'll have to listen for event changes (specifically
.movieRecordingStarted
and.movieRecordingFinished
) and figure it out on your own. In UIKit, this is done by setting or overriding aUIViewController
'ssupportedInterfaceOrientations
property. There isn't currently a way to limit app rotations per view in SwiftUI.
Most of the behind-scenes-code stems directly from Apple's AVCam tutorial. I started with the current version of it (parts of which require iOS 17/Xcode 15), and I made it backwards-compatible to iOS 13. I also reworked parts of the code to work with properties of AVCaptureViewModel
, as well as to replace @IBAction
s and @IBOutlets
. Additionally, I turned their PreviewView
into CameraPreviewView
and wrapped it with CameraPreview
.