I have some code below that records videos using AVFoundation. When my app launches I get the warning “Publishing changes from within view updates is not allowed, this will cause undefined behavior” on the line “@StateObject var cameraModel = CameraViewModel()”. I tried debugging this but couldn’t find a way to get ride of it. Is this related to using @StateObject?
import SwiftUI
import SwiftUI
import AVKit
import AVFoundation
struct HomeStory: View {
@StateObject var cameraModel = CameraViewModel()
var body: some View {
ZStack(alignment: .bottom) {
}
}
}
struct CameraPreview: UIViewRepresentable {
@EnvironmentObject var cameraModel : CameraViewModel
var size: CGSize
func makeUIView(context: Context) -> UIView {
let view = UIView()
cameraModel.preview = AVCaptureVideoPreviewLayer(session: cameraModel.session)
cameraModel.preview.frame.size = size
cameraModel.preview.videoGravity = .resizeAspectFill
view.layer.addSublayer(cameraModel.preview)
DispatchQueue.global(qos: .userInitiated).async {
cameraModel.session.startRunning()
}
return view
}
func updateUIView(_ uiView: UIView, context: Context) { }
}
class CameraViewModel: NSObject, ObservableObject, AVCaptureFileOutputRecordingDelegate {
@Published var session = AVCaptureSession()
@Published var alert = false
@Published var output = AVCaptureMovieFileOutput()
@Published var preview : AVCaptureVideoPreviewLayer!
@Published var isRecording: Bool = false
@Published var recordedURLs: [URL] = []
@Published var previewURL: URL?
@Published var showPreview: Bool = false
@Published var recordedDuration: CGFloat = 0
@Published var maxDuration: CGFloat = 20
func checkPermission(){
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized:
setUp()
return
case .notDetermined:
AVCaptureDevice.requestAccess(for: .video) { (status) in
if status{
self.setUp()
}
}
case .denied:
self.alert.toggle()
return
default:
return
}
}
func setUp(){
do{
self.session.beginConfiguration()
let cameraDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)
let videoInput = try AVCaptureDeviceInput(device: cameraDevice!)
let audioDevice = AVCaptureDevice.default(for: .audio)
let audioInput = try AVCaptureDeviceInput(device: audioDevice!)
// MARK: Audio Input
if self.session.canAddInput(videoInput) && self.session.canAddInput(audioInput){
self.session.addInput(videoInput)
self.session.addInput(audioInput)
}
if self.session.canAddOutput(self.output){
self.session.addOutput(self.output)
}
self.session.commitConfiguration()
}
catch {
print(error.localizedDescription)
}
}
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
}
func mergeVideos(assets: [AVURLAsset],completion: @escaping (_ exporter: AVAssetExportSession)->()) async {
}
}




