I have created a video recorder which works fine if I use it on a phone. Now I want to control it (open that view/camera and start/stop recording from the watch).
What I've did is I have created an ObservableObject
and added a state for the .fullScreenCover
which opens/hides camera.
I can open the camera from the watch by calling a function
func sendCommand(_ command: ConnectivityCommands) {
guard canSendToPeer() else { return }
WCSession.default.sendMessage(["command" : command.rawValue],replyHandler: nil) { error in
print("Cannot send message: \(String(describing: error))")
}
}
and receiving it:
func session(
_ session: WCSession,
didReceiveMessage message: [String : Any]
) {
if let cammandValue = message["command"] {
guard let command = ConnectivityCommands(rawValue: cammandValue as! Int) else { return }
DispatchQueue.main.async { [weak self] in
switch command {
case ConnectivityCommands.openPhoneCamera:
self?.cameraOpen = true
}
}
}
Main View that holds the camera view
.fullScreenCover(isPresented: $connectivityManager.cameraOpen, content: {
VideoRecorderView()
})
WatchConnectivityManager
final class WatchConnectivityManager: NSObject, ObservableObject {
static let shared = WatchConnectivityManager()
@Published var cameraOpen: Bool = false // <<====
and View
import SwiftUI
import AVKit
import AVFoundation
struct VideoRecorderView: View {
@EnvironmentObject private var assetsStoreVM: AssetsStoreViewModel
@EnvironmentObject var connectivityManager: WatchConnectivityManager
@StateObject var cameraVM: CameraViewModel = .init()
@StateObject var stopWatch = StopWatch()
private let fileManager = LocalFileManagerService.shared
var body: some View {
VStack {
// camera output...
HStack {
if !cameraVM.isRecording {
Button(action: {
connectivityManager.cameraOpen = false
}, label: {
Image(systemName: "xmark").resizable().frame(width: 30, height: 30)
})
}
}
Spacer()
Button(action: {
if !cameraVM.isRecording {
stopWatch.start()
cameraVM.startRecording(completion: { (url, error) in
assetsStoreVM.refreshAssets()
})
} else {
stopWatch.stop()
cameraVM.stopRecording()
}
}, label: {
Image(systemName: cameraVM.isRecording ? "stop.circle" : "record.circle")
.font(.system(size: 80))
.foregroundColor(.red)
})
.padding()
}.onDisappear {
cameraVM.captureSession.stopRunning()
}
}
}
So now I would like to call a cameraVM.startRecording()
from VideoRecorderView
How to do it right?