skip to Main Content

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:

  1. SwiftUI -> Thread 1: Fatal error: No observable object of type
  2. 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


  1. Chosen as BEST ANSWER

    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


  2. You can´t instantiate the UIApplicationDelegateAdaptor yourself. The system will do that for you. But there is a workaround.

    From Documentation

    If your app delegate conforms to the ObservableObject protocol, as in the example above, then SwiftUI puts the delegate it creates into the Environment. You can access the delegate from any scene or view in your app using the EnvironmentObject property wrapper:

    This means get rid of your CameraManager, move the functions into AppDelegate and conform it to ObservableObject then you can access it in every subview from the Environment as AppDelegate.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search