Reputation: 27133
I want a single point in my app where I can store some data and quick access it. Before SwiftUI I just had ApplicationDelegate
for this purposes. Before I just needed to call kind of appDelegate.userService
and it provides to me a single point in app which was initialised once. No more singletons at all just appDelegate.
Now I found this tutorial how to use @EnvironmentObject
I have added this code here to init my userService:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var userService = UserService()
...
Also I have this code in my view:
struct LoginView: View {
@EnvironmentObject var userService: UserService
var body: some View {
...
In the above LoginView
I have a function to fetch a user from the server by email:
func fetchUser(with email: String) {
userService.getUser(with: email) { (result) in
switch result {
case .success(let user):
self.userService.user = user // update user in user service after fetch
self.showWelcomeView = true
break
case .failure:
break
}
self.showActivityIndicator = false
}
}
But when I try to call getUser
function I get this error:
Fatal error: No ObservableObject of type UserService found.
A View.environmentObject(_:) for UserService may be missing as an ancestor of this view.: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-39.4.3/Core/EnvironmentObject.swift, line 55
2020-04-18 23:52:41.774988+0300 BusinessTool[7426:730172] Fatal error: No ObservableObject of type UserService found.
A View.environmentObject(_:) for UserService may be missing as an ancestor of this view.: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-39.4.3/Core/EnvironmentObject.swift, line 55
Here is my user service:
class UserService: ObservableObject {
enum UserFetchResult {
case success(data: User)
case failure
}
typealias UserServiceResponse = (User?, NSError?) -> Void
@Published var user = User(username: "", email: "")
...
The main question is how to resolve the issue above?
I also have side questions:
@EnvironmentObject
) at all or it's better to use AppDelegate as before appDelegate.userService
and store all needed data there, I don't see any advantages of this thing.ObservableObject
as to me user service is more about execution some functionality (fetch user data, update user data on the server, in the local storage and etc) rather than data model layer which we need to observe. Confused at all here. In the link I provided above Paul uses this ObservableObject
for app settings, not sure this is right.Upvotes: 1
Views: 1703
Reputation: 861
In your SceneDelegate
you should call .environmentObject(userService)
on your root view (LoginView
).
Upvotes: 2