在我的应用程序中,我想在环境中存储一个对象,以便从各种视图执行网络查询。但是,在开发过程中,我想改用模拟,并从应用程序的捆绑包中检索有效负载(JSON 格式(。这些是我采取的步骤:
- 指定协议
typealias Token = String
protocol MyAPIConforming {
func signIn(username: String, password: String, completion: @escaping (Token?, Error?) -> Void)
}
- 实现我需要的两个类
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
}
}
- 在
- 环境中注入模拟对象
let myManager = MockMyAPIManager()
// Create the SwiftUI view that provides the window contents.
let contentView = LoginView().environmentObject(myManager)
- >在视图中声明@Environment对象
struct LoginView: View {
@EnvironmentObject var myManager: MyAPIConforming
...
我确实将myManager
声明为MyAPIConforming
,因为我可以传递类型为MockMyAPIManager
或MyAPIManager
的对象。
但是,在步骤#4中,我收到以下错误:
属性类型">MyAPIConforming"与其包装器类型"EnvironmentObject"的"wrappedValue"属性不匹配
我不确定该错误是否意味着无法保证采用 toMyAPIConforming
的对象也将采用ObservableObject
协议。
那么,我需要怎么做才能在环境中存储MockMyAPIManager
或MyAPIManager
呢?这可能吗?
这是一个可能的解决方案
struct LoginView<T: ObservableObject & MyAPIConforming>: View {
@EnvironmentObject var myManager: T
// other code here
}
更新:使用情况
对于内容视图
LoginView<MyAPIManager>().environmentObject(MyAPIManager())
以及用于测试/预览
LoginView<MockMyAPIManager>().environmentObject(MockMyAPIManager())