How do I get the data from the CameraService after the videoClips array is populated from a button in the CameraView.
I would like to be able to press a button and move to a new screen passing along an array of AVPlayerItems.
My button always prints 0 even after I know there is data in the array in the CameraService
public class CameraService: NSObject, AVCaptureFileOutputRecordingDelegate {
@Published public var videoClips = [AVPlayerItem]()
public func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
let video: AVPlayerItem = AVPlayerItem(url:outputFileURL)
videoClips.append(video)
}
}
final class CameraModel: ObservableObject {
private let service = CameraService()
var videoClips: [AVPlayerItem]
init() {
videoClips = service.videoClips
}
}
struct CameraView: View {
@StateObject var model = CameraModel()
var body: some View {
Button("video") {
print(model.videoClips.count)
}
}
}
In its current form, model.videoClips.count
will only ever be 0, because you set videoClips
in init()
and then it never gets updated again.
I'm guessing that you're assuming it'll be updated because CameraService.videoClips
is a @Published
property. But, @Published
only gets watched automatically by View
s and their ObservableObject
s. So, two problems here: a) CameraService
is not an ObservableObject
and CameraModel
is not a View
.
My first recommendation fix this would be to ditch CameraModel
completely. Maybe it's a function of trying to make a minimal example, but in its current form, it's not doing anything -- it's just a non-functional middleman. So, turn CameraService
into an ObservableObject
, which would mean that the @Published
property would work and you'd be good-to-go.
Regarding the navigation to another screen, that's probably best for a separate question, but I'll leave a brief answer here:
//in your view
NavigationLink(destination: DetailView(videoClips: service.videoClips)) {
Text("Link")
}
(This is assuming you've turned CameraService
into your ObservableObject
)
If for some reason you did need both CameraModel
and CameraService
, you can hook up the two by doing something like this:
class CameraModel : ObservableObject {
private let service = CameraService()
@Published var videoClips : [AVPlayerItem] = [] //note that this is @Published now
init() {
service.$videoClips.assign(to: &self.$videoClips) //use a Combine Publisher to get updates from the CameraService videoClips and assign them to this class's videoClips any time there's an update
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.