I am working on an app that uses an AVCaptureLayer to display a video preview layer and also a text representation of the brightness (calculated from the video metadata). I've tried to make my app more efficient by only creating one AVCaptureSession in a class VideoStream and I want to then pass the capture session to a UIViewRepresentable that creates a UIView showing the video preview layer. The View is straightforward:
struct ContentView: View {
@StateObject var videoStream = VideoStream() // holds session variable for AVCaptureSession
var body: some View {
VStack {
VideoPreviewHolder(runningSession: videoStream.session) // videoStream.session not initialized at build time
}.frame(width: 300, height: 300, alignment: .center)
Text(String(format: "%.2f Lux", videoStream.luminosityReading))
.font(.largeTitle)
}
}
Does SwiftUI provide a way to await the initialization of a StateObject class? The init() method for VideoStream() calls a function responsible for first checking for camera authorization and if necessary requesting it, and if authorization is granted then a second function is called which configures the AVCaptureSession. This all takes quite a bit of time, especially if the user needs to grant or deny the authorization.
I've tried adding await / async to the VideoStream() initializer and the functions called therein, but since my VideoStream() class inherits from NSObject, I receive an error that async initializer cannot be represented in Objective-C.
Is there a SwiftUI specific way of awaiting the StateObject's initialization?
@StateObject. What you must be looking for is awaiting something else async that is being dispatched inside theinitofVideoStream(like asking for authorization). The code here is not enough to represent the issue.init()ofVideoStream. Put these in the.onAppear{...}or a.task{...}of the View instead. There, you can use theawait/asyncif needed.