SwiftUI 依赖项

基于 SwiftUI-Environment 的依赖注入

用法

首先,创建您的依赖项,通过为它们创建 DependencyKey 并将它们添加到 DependencyValues 中,类似于声明 SwiftUI-Environment 值。但除了 defaultValue 之外,您还需要提供 previewValue (自动在 SwiftUI 预览中使用) 和 testingValue (自动在单元测试中使用)。

之后,您可以在 ViewModels 和 Views 中访问这些依赖项。

设置

private struct MyDependencyKey: DependencyKey {
    static var defaultValue: String {
        "Default"
    }
    
    static var previewValue: String {
        "Preview"
    }
    
    static var testingValue: String {
        "Testing"
    }
}

extension DependencyValues {
    var myDependency: String {
        get { self[MyDependencyKey.self] }
        set { self[MyDependencyKey.self] = newValue }
    }
}

您可以始终为视图提供自定义值。该值将在视图层次结构中传播。

ContentView()
    .dependency(\.myDependency, "New Value")

ObservableObject 中的用法

视图模型应该遵循 ObservableDependencyObject 而不是遵循 ObservableObject。当前上下文的 DependencyValues 将在所需的初始化器中提供。

final class ViewModel: ObservableDependencyObject {
    required init(dependencies: DependencyValues) {
        // Access the dependencies needed for this ViewModel
    }
}

struct ContentView: View {
    @DependencyObject private var viewModel: ViewModel
    
    var body: some View {
        ...
    }
}

如果您需要视图模型的自定义初始化器,您可以像这样使用依赖项初始化视图模型

final class ViewModel: ObservableDependencyObject {
    let customProperty: String
    
    required init(customProperty: String, dependencies: DependencyValues) {
        self.customProperty = customProperty
        // Access the dependencies needed for this ViewModel
    }
}

struct ContentView: View {
    @DependencyObject private var viewModel: ViewModel
    
    init() {
        _viewModel = DependencyObject { dependencies in
            ViewModel(customProperty: "Custom", dependencies: dependencies)
        }
    }
    
    var body: some View {
        ...
    }
}

Obervable 一起使用

模型应该遵循 ObservableDependency,并且不应该在视图中使用 State 注释模型,而应该使用 DependencyState 注释模型。当前上下文的 DependencyValues 将在所需的初始化器中提供。

@Observable
final class Model: ObservableDependency {
    required init(dependencies: DependencyValues) {
        // Access the dependencies needed for this ViewModel
    }
}

struct ContentView: View {
    @DependencyState private var model: Model
    
    var body: some View {
        ...
    }
}

在 View 中的用法

您可以通过使用 Dependency 注释直接在视图中访问依赖项。

struct ContentView: View {
    @Dependency(\.myDependency) private var myDependency
    
    var body: some View {
        Text(myDependency)
    }
}

演示

请参阅演示项目获取一些示例实现

许可证

请参阅LICENSE