在 ObservableObject 中引用 EnvironmentObject

Iva*_*old 6 swiftui combine observableobject

如果用户未登录,我有一个 LoginView 显示一个 RegisterView,如果他登录则显示一个 ContentView:

struct LoginView: View {
    @EnvironmentObject var userManager: UserManager
    var body: some View {
        Group {
            if userManager.isRegistered {
                ContentView()
            } else {
                RegisterView()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ContentView具有三个ObservedObject属性,使用组合从带有其余 api 的服务器获取内容。

struct ContentView: View {
    @EnvironmentObject var userManager: UserManager
    @ObservedObject var usersStore = UsersStore()
    @ObservedObject var rolesStore = RolesStore()
    @ObservedObject var elementsStore = ElementsStore()

    var body: some View {
        NavigationView {
            ZStack {
                Image("stell")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .opacity(0.1)

                VStack(alignment: .leading, spacing: 5) {
                    NavigationLink(destination: UsersView(usersStore: usersStore) ) {
                        Text("Users")
                    }
                    NavigationLink(destination: RolesView(rolesStore: rolesStore)) {
                        Text("Roles")
                    }
                    NavigationLink(destination: ElementsView(elements: $elementsStore.elements)) {
                        Text("Elements")
                    }
                }.font(.title).padding(20)
            }.navigationBarTitle(Text("STELL"))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

userManager遇到的问题是我想从任何观察到的对象中引用,例如当401 Unauthorized会话令牌过期时其余 api 返回时。然后我希望 ObservedObject 将isRegistered标志设置为userManagerfalse以便RegisterView自动显示。但是我该怎么做呢?我无法userManager在任何 ObservedObject 属性初始值设定项中设置引用,因为编译器抱怨属性初始值设定项在self可用之前运行。

Asp*_*eri 7

在这种情况下,我会通过构造函数使用依赖注入...下面是示例的可能方法UsersStore,对于其他人来说是相同的

改变在 UsersStore

class UsersStore: ObservableObject {
    var manager: UserManager

    init(manager: UserManager) { // << inject UserManager via constructor
        self.manager = manager 
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

改变在 ContentView

struct ContentView: View {
    @EnvironmentObject var userManager: UserManager
    @ObservedObject var usersStore: UsersStore

    init(usersStore: UsersStore) {
        self.usersStore = usersStore // << inject UsersStore via contructor
    }
Run Code Online (Sandbox Code Playgroud)

用途的变化

struct LoginView: View {
    @EnvironmentObject var userManager: UserManager
    var body: some View {
        Group {
            if userManager.isRegistered {
                // userManager is valid here some UsersStore can be created
                ContentView(usersStore: UsersStore(manager: self.userManager))
Run Code Online (Sandbox Code Playgroud)