在启动时从服务器加载数据到iOS应用程序,并在重载视图时重用它



我正在用SwiftUI构建一个电子商务应用程序,需要在加载许多视图之前从服务器检索一些数据。我想知道正确的方法来检索和存储这些数据。

目前,在主页上,应用程序向服务器请求一些要显示的图片的名称,然后使用AsyncImage从服务器加载每个图片。目前,我正在视图中创建一个@State变量来存储图像名称,并在.task中加载数据:


struct CoverImagesTabView: View {

@State var coverImageNames: [String] = []
var body: some View {
TabView {
ForEach(coverImageNames, id: .self) { coverImage in
CoverImageView(coverImage: coverImage)
.padding(.top, 10)
.padding(.horizontal, 15)
} //: LOOP
} //: TAB
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
.task {
await getCoverImageNames { imageNames in
coverImageNames = imageNames
}
}
}
}

getCoverImageNames函数看起来像

import Alamofire
func getCoverImageNames(_ callback: @escaping (_ decoded: [String]) -> Void) async {
AF.request("http://(serverIP)/api/offerings/marketing/coverImages")
.responseDecodable(of: [String].self) { response in
if response.value != nil {
callback(response.value ?? [])
print("Cover image names retrieved")
} else {
print("Could not access cover image names")
}
}
}
然后在CoverImageView中使用coverImageNames来加载图像。我计划使用相同的策略来检索其他数据,例如产品列表。

这个方法有点笨拙,主要是因为它每次重新加载视图时都会调用API来设置coverImageNames的值;这些数据实际上只需要在每次应用启动时加载一次。在Swift中有特定的方法来做到这一点吗?

如果我创建一个符合ObservableObject的类,并将它的一个实例作为@StateObject传递给这个视图,它解决了重新加载问题,但如果我必须创建一个全新的类,只是为了表示[String],它只加载一次,这不是很有效。

我还考虑过使用Core Data来保存服务器上的数据,但这似乎有点过头了。

是否有一个内置的方式来加载我的数据一次,然后继续重用它每次视图被重新加载?还是状态对象方法是最有效/唯一的方法?

我会创建一个Observable类,并通过@EnvironmentObject在整个应用程序中共享它的一个实例。

如果加载一次后没有改变,就不需要使用@StateObject,因为不需要更新视图。

class YourModel : ObservableObject {
var coverImageNames: [String] = []
init() {
fetchImageNames()
}
func fetchImageNames() {
// load the names of `some` images from the server using URLSession or whatnot and update coverImageNames
}
}
struct YourApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(YourModel())
}
}
}
struct YourView1: View {
@EnvironmentObject var m: YourModel
var body: some View {
// use m.coverImageNames
}
}
struct YourView2: View {
@EnvironmentObject var m: YourModel
var body: some View {
// use m.coverImageNames
}
}

如果你不喜欢在每个视图中重复调用AsyncImage,我会在init期间构建一个UIImage集合,以便它可以在任何视图中重用。构建集合可以是同步的或异步的,两者都有利弊,这取决于情况,所以这是你的选择。

相关内容

  • 没有找到相关文章

最新更新