使用swift显示来自2个不同网络请求的数据的最佳方式是什么?
我目前有两个网络请求,其中一个需要另一个的输入来开始获取数据。从同一列表中的两个网络请求获取和显示数据(在本例中,数据是每个网络请求的一个数组)的最佳方式是什么 这是我的密码:使用swift显示来自2个不同网络请求的数据的最佳方式是什么?,swift,xcode,Swift,Xcode,我目前有两个网络请求,其中一个需要另一个的输入来开始获取数据。从同一列表中的两个网络请求获取和显示数据(在本例中,数据是每个网络请求的一个数组)的最佳方式是什么 这是我的密码: VStack { List(viewModel.work, id: \.id) { work in VStack { Text("(work.name)") }.onAppear { fetchMoneyAmoun
VStack {
List(viewModel.work, id: \.id) { work in
VStack {
Text("(work.name)")
}.onAppear {
fetchMoneyAmount(workType: work.type)
}
ForEach(viewModel.moneyAmount, id: \.id) { moneyAmt in
Text("maxMoney: (moneyAmt.maxAmount)")
}
}
}
.onAppear {
fetchWork()
}
我现在的问题是网络请求(fetchMoneyAmount)似乎在从viewModel.work数组中显示每个列表项时提取数据。每个工作列表磁贴都具有相同的MoneyAmount值,但不应如此。每个工作瓷砖应有不同的金额
我真的不知道如何发出fetchMoneyAmount网络请求,因为它需要从第一个网络请求生成的值 如有任何建议,将不胜感激
每个“工作”项在JSON中都有一个“moneyAmount”项。我需要从每个工作项中获取moneyAmount,然后显示相应“工作”项的每个moneyAmount。我建议您只需创建一个
最终类DataProvider:ObservableObject
类,该类根据每个oter执行两个请求。为此,您有几个选项:
@ObservedObject var dataProvider=dataProvider()
现在,每当数据提供程序发布新数据时,视图都会自动重新绘制
示例代码
它向您展示了如何将数据提供程序可观察对象链接到显示结果的SwiftUI代码。这样想:
“无论何时重新绘制视图,都假定您的数据已准备好使用”
记住这一点,您只需要编写视图代码,就好像您的数据已经在本地属性中可用一样。但是属性由数据提供程序提供,它告诉视图何时更新
数据提供者
通过几行代码,您可以扩展DataProvider,以便在第一个请求完成时加载第二个请求
class DataProvider: ObservableObject {
@Published private(set) var emojis: [Emoji] = []
private var cancellable: Any?
private var urlSession = URLSession.shared
func readEmojiData(url: URL) {
cancellable = urlSession
.dataTaskPublisher(for: url)
.map { self.emojisFromRawData($0.data) }
.replaceError(with: [])
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
.assign(to: \.emojis, on: self)
}
}
看法
“发出fetchMoneyAmount网络请求,因为它需要从第一个网络请求生成的值”您需要序列化它们。在我看来,联合框架是最好的方式。您需要收集所有数据并将其放入数据模型,这将触发接口更新。除了下面的答案之外,我建议您阅读本文。本文详细解释了链接:谢谢。我一直在尝试设置第二个网络请求,它需要来自第一个网络请求的输入,但仍然没有成功。您还建议在DataProvider类中添加什么来嵌入第二个网络请求?提前感谢您的帮助。由于某些原因,每个工作列表磁贴仍具有相同的MoneyAmount值,但不应如此。每个工作磁贴应该有不同的MoneyAmounts。您必须为每个请求创建一个函数。这些函数返回一个发布服务器,然后可以将其连接在一起。请参阅中的“查林请求”
import SwiftUI
struct EmojiGrid : View {
@ObservedObject var dataProvider = DataProvider()
@ScaledMetric(relativeTo: .largeTitle) var spacing: CGFloat = 12
@ScaledMetric(relativeTo: .largeTitle) var size: CGFloat = 50
private var columns: [GridItem] {
[GridItem(.adaptive(minimum: size))]
}
private var versions: [Emoji.Version] {
Emoji.Version.allCases.map { $0 }.sorted().reversed()
}
init() {
dataProvider.readEmojiData(url: URL("https://..."))
}
var body: some View {
NavigationView {
ScrollView {
LazyVGrid(columns: columns, spacing: spacing, content: {
ForEach(dataProvider.emojis, id: \.id) { emoji in
Button(emoji.emoji, action: { print(emoji) })
.font(.largeTitle)
.frame(width: size, height: size, alignment: .center)
}
})
.padding([.trailing, .leading], spacing)
}
}
}
}