VisionCamera is a powerful, high-performance Camera framework for SwiftUI and UIKit, built on AVFoundation. It brings the camera engine from react-native-vision-camera to native iOS apps. It features:
- Photo capture, RAW photos, and Video recording with audio
- SwiftUI and UIKit previews, smooth zooming, and tap-to-focus
- Customizable devices, multi-cameras, resolutions, and FPS
- Persistent recordings that keep going while you flip the Camera
- Frame and depth outputs for image processing, computer vision, and realtime video
- QR/Barcode and face detection through AVFoundation
- Video HDR, stabilization, and manual Camera controls
Requires iOS 15.1 or later. Start with SwiftUI and Swift Package Manager. UIKit and CocoaPods are equally functional, actively maintained alternatives. Other Apple platforms are planned.
VisionCamera requires Xcode 26.2 or later and supports iOS 15.1 or later. The package uses Swift 5 language mode and has no external dependencies.
- In Xcode, choose File > Add Package Dependencies.
- Enter
https://github.com/margelo/VisionCamera.git. - Until the first release containing
Package.swift, select the Branch dependency rule and entermain. The existing0.1.0tag does not include the package manifest. - Add the VisionCamera library product to your app target.
While the repository is private, authenticate with a GitHub account that has access. For SSH authentication, use ssh://[email protected]/margelo/VisionCamera.git with a configured GitHub SSH key.
For another Swift package, add the dependency and library product to your Package.swift:
dependencies: [
.package(url: "https://github.com/margelo/VisionCamera.git", branch: "main")
],
targets: [
.target(
name: "YourApp",
dependencies: [
.product(name: "VisionCamera", package: "VisionCamera")
]
)
]After the first SPM release, use a version requirement instead of branch: "main". For a 0.1.1 release, use .upToNextMinor(from: "0.1.1") to receive compatible 0.1.x updates. Use a released version containing Package.swift before publishing a package that depends on VisionCamera.
Add VisionCamera to your Podfile:
pod 'VisionCamera',
:git => '[email protected]:margelo/VisionCamera.git',
:branch => 'main'Run pod install and open your app's .xcworkspace.
While the repository is private, your GitHub account needs access.
These docs describe the current main branch. The 0.1.0 tag is the initial extraction and has an older API.
Pin a release tag once a release containing these changes is available.
..and get started by setting up permissions!
Add NSCameraUsageDescription to your app's Info.plist, then mount a Camera:
import SwiftUI
import VisionCamera
struct CameraScreen: View {
@Environment(\.scenePhase) private var scenePhase
@State private var device: CameraDevice?
@State private var message = "Requesting Camera access..."
var body: some View {
Group {
if let device {
Camera(device: device, isActive: scenePhase == .active)
.enableZoomGesture()
.enableTapToFocusGesture()
} else {
Text(message)
}
}
.task {
do {
guard try await VisionCamera.requestCameraPermission() else {
message = "Camera access was denied. Enable it in Settings."
return
}
device = VisionCamera.defaultCamera(for: .back)
if device == nil { message = "No Camera is available." }
} catch {
message = error.localizedDescription
}
}
}
}Camera configures and starts its session when mounted and active, and stops it when removed. Set isActive to false when a retained screen is hidden. Keep capture outputs in a model owned by @StateObject so SwiftUI updates reuse them. See the SwiftUI guide for photos, configuration, and callbacks.
The repository includes two runnable apps with permissions, lifecycle handling, photos, and both video recorders:
- SwiftUI example: open
ExampleSwiftUI/VisionCameraSwiftUIExample.xcodeproj. It uses the local Swift package. - UIKit example: run
bundle exec pod installinExample, then openExample/VisionCameraExample.xcworkspace. It uses the local development Pod.
Choose an iPhone destination and run the app. For a physical device, select your development team under Signing & Capabilities. Camera capture requires a physical device.
Add VisionCameraResizer for GPU frame resizing, VisionCameraBarcodeScanner for ML barcode detection through Apple Vision, or VisionCameraLocation for explicit foreground location updates. Each is a separate SPM product and CocoaPod with the same Swift import. Core alone does not include their implementations.
The barcode scanner requires iOS 16. Core, resizer, and location support iOS 15.1. Location permission requests occur only through explicit calls in the optional location module.
See optional installation and native usage and the optional feature example.
Read the guides and API reference on the documentation website. They are written with DocC, Apple's documentation compiler. You can also read the guides here, open them in Xcode, or build the website locally.
The Apple API audit and migration notes explain the compatibility APIs removed from the original extraction and their native replacements.
Open Package.swift in Xcode, select the VisionCamera scheme and an iOS simulator, then choose Product > Test.
To build for iOS from the command line:
xcodebuild -scheme VisionCamera -configuration Release \
-destination 'generic/platform=iOS' \
-derivedDataPath build/spm-device CODE_SIGNING_ALLOWED=NO buildTo run the existing tests, replace <simulator-udid> with an available iOS simulator identifier from xcrun simctl list devices available:
xcodebuild -scheme VisionCamera \
-destination 'platform=iOS Simulator,id=<simulator-udid>' \
-derivedDataPath build/spm-simulator CODE_SIGNING_ALLOWED=NO testThe framework imports UIKit and requires an iOS destination. swift test on the macOS host cannot build it.
For release instructions, see Publishing.
VisionCamera is built by Margelo. We make apps better and faster.
- Community Discord
- Follow me on Twitter for updates
- Check out my blog for examples and experiments
- MIT License