将数据从委托Swift类传递到SwiftUI结构中的EnvironmentObject

将数据从委托Swift类传递到SwiftUI结构中的EnvironmentObject,swift,swiftui,watchos,Swift,Swiftui,Watchos,如何将Swift类中委托触发的方法中的传入数据传递给EnvironmentObject 我知道,要使其工作,我的Swift类需要从SwiftUI结构调用/初始化(作为父SwiftUI结构的子级)。但是,我在Apple Watch应用程序的ExtensionLegate中初始化了我的Swift类。我希望在更新名称时看到UI文本元素的更改 以下代码在Apple Watch上运行: class User: ObservableObject { @Published var id: U

如何将Swift类中委托触发的方法中的传入数据传递给EnvironmentObject

我知道,要使其工作,我的Swift类需要从SwiftUI结构调用/初始化(作为父SwiftUI结构的子级)。但是,我在Apple Watch应用程序的ExtensionLegate中初始化了我的Swift类。我希望在更新名称时看到UI文本元素的更改

以下代码在Apple Watch上运行:

class User: ObservableObject {
    
    @Published var id: UUID?
    @Published var name: String?
}

依赖注入

解决方案之一是全局存储对
@EnvironmentObject
的引用,例如,在某个依赖项容器中

enum Dependencies {
    struct Name: Equatable {
        let rawValue: String
        static let `default` = Name(rawValue: "__default__")
        static func == (lhs: Name, rhs: Name) -> Bool { lhs.rawValue == rhs.rawValue }
    }

    final class Container {
        private var dependencies: [(key: Dependencies.Name, value: Any)] = []

        static let `default` = Container()

        func register(_ dependency: Any, for key: Dependencies.Name = .default) {
            dependencies.append((key: key, value: dependency))
        }

        func resolve<T>(_ key: Dependencies.Name = .default) -> T {
            return (dependencies
                .filter { (dependencyTuple) -> Bool in
                    return dependencyTuple.key == key
                        && dependencyTuple.value is T
                }
                .first)?.value as! T
        }
    }
}
您可以从代码中的任何位置访问它:

let user: User = Dependencies.Container.default.resolve()
user.modify()
有关Swift的
依赖项注入
的更详细说明,请参见

单身人士

或者,您可以使用标准的
Singleton
模式使您的用户数据在全球范围内可用。可以找到更详细的解释

最后的想法


这是一个很好的例子(至少在我看来),说明了如何以干净的方式编写iOS应用程序。这有点复杂,但您可以选择一些部分。

依赖注入

解决方案之一是全局存储对
@EnvironmentObject
的引用,例如,在某个依赖项容器中

enum Dependencies {
    struct Name: Equatable {
        let rawValue: String
        static let `default` = Name(rawValue: "__default__")
        static func == (lhs: Name, rhs: Name) -> Bool { lhs.rawValue == rhs.rawValue }
    }

    final class Container {
        private var dependencies: [(key: Dependencies.Name, value: Any)] = []

        static let `default` = Container()

        func register(_ dependency: Any, for key: Dependencies.Name = .default) {
            dependencies.append((key: key, value: dependency))
        }

        func resolve<T>(_ key: Dependencies.Name = .default) -> T {
            return (dependencies
                .filter { (dependencyTuple) -> Bool in
                    return dependencyTuple.key == key
                        && dependencyTuple.value is T
                }
                .first)?.value as! T
        }
    }
}
您可以从代码中的任何位置访问它:

let user: User = Dependencies.Container.default.resolve()
user.modify()
有关Swift的
依赖项注入
的更详细说明,请参见

单身人士

或者,您可以使用标准的
Singleton
模式使您的用户数据在全球范围内可用。可以找到更详细的解释

最后的想法


这是一个很好的例子(至少在我看来),说明了如何以干净的方式编写iOS应用程序。这有点复杂,但你可以挑选一些零件。

这看起来非常复杂。特别是当自定义对象很复杂时。我对EnvironmentObject的理解是允许在应用程序范围内共享数据及其更新。这不需要在顶部设置依赖项。虽然我确信这是一种方法,但它感觉不到快捷。没错,它很复杂。
EnvironmentObject
的问题在于它是一种单例对象,但仅适用于SwiftUI
视图。如果您想要一个简单的解决方案,请尝试使用普通单例。类似的问题是。因此,在SwiftUI中使用Swift类的唯一方法是从SwiftUI中调用类和方法,例如在.onAppear{self.userEnv.name=watchConnectionProvider.shared.getData()}?如果我想获得定期更新,我必须在一个计时器间隔内调用该方法。这感觉像是一个不成熟的设计。我不想让我的应用程序逻辑驻留在Swift类中吗?如果您想遵循
MVVM
模式,您可以拥有一个
ViewModel
类,其中包含您的业务逻辑,并将其作为
视图中的
观察对象
。您可以像
.onAppear{self.viewModel.load()}
一样使用它。对于在
ViewModel
中访问env对象的问题,我建议使用
依赖项注入
。否则,据我所知,只剩下一个
Singleton
。记住,这仍然是SwiftUI的早期阶段。未来可能会有更好的解决方案。这是一篇关于如何以简洁的方式编写iOS应用程序的好文章。这看起来非常复杂。特别是当自定义对象很复杂时。我对EnvironmentObject的理解是允许在应用程序范围内共享数据及其更新。这不需要在顶部设置依赖项。虽然我确信这是一种方法,但它感觉不到快捷。没错,它很复杂。
EnvironmentObject
的问题在于它是一种单例对象,但仅适用于SwiftUI
视图。如果您想要一个简单的解决方案,请尝试使用普通单例。类似的问题是。因此,在SwiftUI中使用Swift类的唯一方法是从SwiftUI中调用类和方法,例如在.onAppear{self.userEnv.name=watchConnectionProvider.shared.getData()}?如果我想获得定期更新,我必须在一个计时器间隔内调用该方法。这感觉像是一个不成熟的设计。我不想让我的应用程序逻辑驻留在Swift类中吗?如果您想遵循
MVVM
模式,您可以拥有一个
ViewModel
类,其中包含您的业务逻辑,并将其作为
视图中的
观察对象
。您可以像
.onAppear{self.viewModel.load()}
一样使用它。对于在
ViewModel
中访问env对象的问题,我建议使用
依赖项注入
。否则,据我所知,只剩下一个
Singleton
。记住,这仍然是SwiftUI的早期阶段。未来可能会有更好的解决方案。这是一篇关于如何以干净的方式编写iOS应用程序的好文章。
Dependencies.Container.default.register(User())
let user: User = Dependencies.Container.default.resolve()
user.modify()