将数据从委托Swift类传递到SwiftUI结构中的EnvironmentObject
如何将Swift类中委托触发的方法中的传入数据传递给EnvironmentObject 我知道,要使其工作,我的Swift类需要从SwiftUI结构调用/初始化(作为父SwiftUI结构的子级)。但是,我在Apple Watch应用程序的ExtensionLegate中初始化了我的Swift类。我希望在更新名称时看到UI文本元素的更改 以下代码在Apple Watch上运行:将数据从委托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
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()