Reputation: 109
I have created an environment object in my scendelegate and want to also use it in another function that resides inside my scenedelegate. The code looks as follows:
SceneDelegate.swift
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
//@EnvironmentObject var data: DataFetcher
var data = DataFetcher()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
let data = (UIApplication.shared.delegate as! AppDelegate).self.data
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(data))
self.window = window
window.makeKeyAndVisible()
}
}
func handleIncomingDynamicLink(_ dynamicLink: DynamicLink){
guard let url = dynamicLink.url else {
print("That's weird. My dynamic link object has no url")
return
}
print("Your incoming link parameter is \(url.absoluteString)")
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
let queryItems = components.queryItems else {return}
self.data.linkRecieved = true
print(data.linkRecieved)
}
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
if let incomingURL = userActivity.webpageURL {
print("Incoming URL is \(incomingURL)")
_ = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { (dynamicLink, error) in
guard error == nil else{
print("Found an error! \(error!.localizedDescription)")
return
}
if let dynamicLink = dynamicLink {
self.handleIncomingDynamicLink(dynamicLink)
}
}
}
}
The problem is that the environment object's linkRecieved variable is not changed inside contentview when the handleIncomingDynamicLink function is executed (I have verified the variable is indeed changed to true once the function is run). Any insight in fixing this issue is much appreciated!!!
Upvotes: 2
Views: 970
Reputation: 114866
You have assigned a DataFetcher
instance to the data
property, presumably to set its type and eliminate the error that your property isn't initialised.
Then in willConnectTo
you get the DataFetcher
instance from your AppDelegate. Your
dataproperty and the local
datavariable in
willConnectTo(That you subsequently add to the environment) now reference different instances of
DataFetcher`, but you didn't realise.
I am not a big fan of assigning "throw away" instances to properties for this reason.
A better approach is to use an implicitly unwrapped optional. That way if you don't assign a value to the property you will get a crash and quickly work out that something isn't right.
Then in willConectTo
you can assign the instance from your AppDelegate
to the property and put it in the environment.
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
//@EnvironmentObject var data: DataFetcher
var data: DataFetcher!
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
self.data = (UIApplication.shared.delegate as! AppDelegate).self.data
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(data))
self.window = window
window.makeKeyAndVisible()
}
}
Upvotes: 2
Reputation: 257729
You need to inject that var data
which is property, so remove the following line
let window = UIWindow(windowScene: windowScene)
//let data = (UIApplication.shared.delegate as! AppDelegate).self.data // << this one
window.rootViewController = UIHostingController(rootView:
ContentView().environmentObject(self.data)) // << inject own property
Upvotes: 2