An ObservableObject view model for capturing photo/video on iOS for SwiftUI and UIKit.


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.

Future and Next Steps

There is still more work to be done to provide more granular control, but it's already functional as it is.

Things to add:

  • 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 of DispatchQueue.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

How to Use AVCaptureViewModel


Misc Notes

  • 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 a UIViewController's supportedInterfaceOrientations 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 @IBActions and @IBOutlets. Additionally, I turned their PreviewView into CameraPreviewView and wrapped it with CameraPreview.


  • Swift Tools 5.8.0
View More Packages from this Author


  • None
Last updated: Wed Apr 03 2024 01:09:22 GMT-0900 (Hawaii-Aleutian Daylight Time)