在环境中存储模拟对象

Store a mock object in the Environment

在我的应用程序中,我想在环境中存储一个对象以从各种视图执行网络查询。但是,在开发过程中,我想改用模拟,并从应用程序包中检索有效负载(JSON 格式)。这些是我采取的步骤:

  1. 指定协议
    typealias Token = String

    protocol MyAPIConforming {
        func signIn(username: String, password: String, completion: @escaping (Token?, Error?) -> Void)
    }
  1. 实现我需要的两个类
    class MockMyAPIManager: MyAPIConforming, ObservableObject {
        func signIn(username: String, password: String, completion: @escaping (Token?, Error?) -> Void) {
            // Read the JSON document from the app's bundle
        }
    }

    class MyAPIManager: MyAPIConforming, ObservableObject {
        func signIn(username: String, password: String, completion: @escaping (Token?, Error?) -> Void) {
            // Perform the network request
        }
    }
  1. 在环境中注入模拟对象
    let myManager = MockMyAPIManager()

    // Create the SwiftUI view that provides the window contents.
    let contentView = LoginView().environmentObject(myManager)
  1. 在视图中声明@Environment 对象
    struct LoginView: View {
    @EnvironmentObject var myManager: MyAPIConforming
    ...

我确实将 myManager 声明为 MyAPIConforming,因为我可以传递 MockMyAPIManagerMyAPIManager.

类型的对象

但是,在第 4 步中出现以下错误:

Property type 'MyAPIConforming' does not match that of the 'wrappedValue' property of its wrapper type 'EnvironmentObject'

我不确定错误是否意味着不能保证采用 MyAPIConforming 的对象也会采用 ObservableObject 协议。

那么我需要做什么才能在环境中存储 MockMyAPIManagerMyAPIManager?这可能吗?

这是一个可能的解决方案

struct LoginView<T: ObservableObject & MyAPIConforming>: View {
    @EnvironmentObject var myManager: T

        // other code here
}

更新: 用法

内容查看

LoginView<MyAPIManager>().environmentObject(MyAPIManager())

和 testing/preview

LoginView<MockMyAPIManager>().environmentObject(MockMyAPIManager())