【发布时间】:2021-07-22 08:13:35
【问题描述】:
我们开始在我们的应用程序中使用 Combine for Networks 调用。用户应该输入一个代码,我们希望通过网络调用验证该代码,然后根据所述网络调用的结果执行操作。
据我们了解,如果我们有一个已发布的字符串变量并使用它来懒惰地创建另一个发布者来进行 API 调用,那么我们只会在每次字符串更改时进行 API 调用。
但是,通过onReceive 监听发布者的 SwiftUI 视图越多,调用的 API 就越多。这是一个简化的示例:
查看
struct ContentView: View {
@ObservedObject var viewModel: ResultBenchmarkViewModel
@State var one: String = "ONE"
@State var two: String = "TWO"
@State var three: String = "THREE"
var body: some View {
VStack {
TextField("INPUT", text: $viewModel.inputString)
Text(one)
.onReceive(viewModel.inputStringPublisher, perform: { string in
one = string
})
Text(two)
.onReceive(viewModel.inputStringPublisher, perform: { string in
two = string
})
Text(three)
.onReceive(viewModel.inputStringPublisher, perform: { string in
three = string
})
}
}
}
视图模型
class ResultBenchmarkViewModel: Identifiable, ObservableObject {
@Published var inputString: String = ""
lazy var inputStringPublisher: AnyPublisher<String, Never> = {
return $inputString
.map { string in
print("API CALL")
return string
}
.eraseToAnyPublisher()
}()
}
使用onReceive 三次也会在用户每次输入字符时打印三次“API CALL”。我们预计会发生的是,“API CALL”只会打印一次,因为inputString 只会更改一次,然后使用onReceive 的三个视图只会收到发布者发布的最终结果。
我们现在正在实施的一个解决方案是监听 inputString,进行 api 调用并将结果保存到本地发布的变量中,然后视图会根据该变量进行更新。但是,对我来说,这似乎是样板文件,如果我们正确实施原始请求,可能会过时。
我们能否通过对实现进行一些小的更改来实现我们的预期结果?还是这里对 combine/swiftui 有根本的误解?
【问题讨论】: