我有一个可以解析json的函数。然后,我使用这些数据来填充一组UI插槽。问题是它是一个很大的json (如果10.1MB很大的话),并且需要5-8秒来加载。在应用程序发布时,这没什么大不了的,但现在它每次都会重新发布这些数据。
现在我只有这样的模式,每个结构视图都是以:
var results = [ScryfallCard]()
.onApear {
results = func()
}
func() -> [ScryfallCard]我一直找不到如何创建一个全局变量,给它分配一个var globleResults = func(),这样我的应用程序就可以预先加载所有的数据,而不需要花5秒的时间加载每个视图。
发布于 2020-07-26 06:58:30
为了使视图能够更新结果,您需要将结果results转换为@State var results: [ScryfallCard] = []
然后,对于处理JSON的函数,无论处理时间有多长,它都应该在results = func()完成后更新视图。
避免使用全局变量,目标是创建不同的组件来封装变量。
你会得到像这样的东西
class NetworkRequester: ObservableObject {
@Published var results: [String] = []
var cancellable: AnyCancellable?
func getResults() {
cancellable = URLSession.shared.dataTaskPublisher(for: URL(fileURLWithPath: "path-to-JSON")!)
.map({ $0.data })
.decode(type: [ScryfallCard].self, decoder: JSONDecoder())
.sink(receiveCompletion: { result in
switch result {
case .failure(let error):
print(error)
case .finished:
break
}
}) { newResults in
self.results = newResults
}
}
}评论中建议的链接是一个有用的资源,可以了解有关如何处理渲染数据的更多信息。
发布于 2020-07-27 04:07:48
好的..。我想通了。有点古怪,但它是有效的。
我基本上必须从顶部开始,并将@EnvironmentObject var globalCards : ScryfallData放入我的ContentView中。在每个视图中添加@ObservedObject var globalCards = ScryfallData()并将globalCards: globalCards传递给下一个视图。然后在最后一个视图中,在我的列表中使用List(globalCards.parsedResults, id: \.id) { item in。
我的print("Parsing...") print("Parsing complete")只在第一次构建时输出,然后再进行下一次解析。(不知何故,即使我滑动退出应用程序,然后再次启动它,它也不会输出print()语句)
https://stackoverflow.com/questions/63091597
复制相似问题