Reputation: 85
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:
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")
}
}
}
}
Upvotes: 0
Views: 1172
Reputation: 85
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
Upvotes: 0
Reputation: 7744
You can´t instantiate the UIApplicationDelegateAdaptor
yourself. The system will do that for you. But there is a workaround.
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
.
Upvotes: 1