The goal is to trigger a navigation transition when the watch sends the signal. I have watch connectivity set up to respond to messages on the iOS side but the environment variable fails to properly attach. Can you tell me the issue with how I have this set-up?
Ive looked at these two posts with the same error but they didn’t solve my issue:
- SwiftUI -> Thread 1: Fatal error: No observable object of type
- SwiftUI @EnvironmentObject error: may be missing as an ancestor of this view
Here’s the code:
App Delegate
class AppDelegate:NSObject, UIApplicationDelegate, WCSessionDelegate {
@EnvironmentObject var cameraManager:CameraManager
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
func sessionDidBecomeInactive(_ session: WCSession) {
}
func sessionDidDeactivate(_ session: WCSession) {
}
func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
guard let request = message["request"] as? String else {
replyHandler([:])
return
}
switch request {
case "test":
replyHandler(["test":"Success"])
case "optionSelected":
replyHandler(["optionSelected":"Success"])
cameraManager.isOptionSelected = true
default:
replyHandler([:])
}
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
if WCSession.isSupported() {
let session = WCSession.default
session.delegate = self
session.activate()
}
return true
}
}
The error i get is "Fatal error: No ObservableObject of type CameraManager found. A View.environmentObject(_:) for CameraManager may be missing as an ancestor of this view." when I try to change the bool
Entrypoint
@main
struct AppName: App {
@StateObject var cameraManager = CameraManager()
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
NavigationView {
ContentView()
}
.environmentObject(cameraManager)
}
}
}
CameraManager
class CameraManager: NSObject, ObservableObject {
@Published var isOptionSelected:Bool = false {
didSet {
if isOptionSelected == true {
print("Success")
}
}
}
}
2
Answers
I'm just posting what I did in case anyone is curious. Instead of trying to use bindings, I just used notification center to post notifications from the app delegate and respond to them from the appropriate views with .onReceive
You can´t instantiate the
UIApplicationDelegateAdaptor
yourself. The system will do that for you. But there is a workaround.From Documentation
This means get rid of your
CameraManager
, move the functions intoAppDelegate
and conform it toObservableObject
then you can access it in every subview from the Environment asAppDelegate
.