如何在SwiftUI中的视图模型之间共享和修改数据?

问题描述 投票:0回答:2

我正在 SwiftUI 中制作一个社交媒体应用程序,但我一直困惑于如何在视图模型之间共享和修改数据。对于每个视图(PostListView、PostDetailView、PostUpdateView),我都有一个单独的视图模型,例如,当用户位于 PostUpdateView 上并对 PostUpdateViewModel 中的帖子进行更改时,如何在 PostListView 上反映这些更改?

// parent view model class PostListViewModel: ObservableObject { @Published var posts = [Post]() // i want changes to any post to be reflected here func fetchPosts() { ... } // fetches posts from rest api, called if self.posts is empty }
// child view model
class PostUpdateViewModel: ObservableObject {
    @Published var post: Post // when updated, i want to see the updated post on the PostListView

    init(post: Post) { self.post = post }

    func update() { ... } // update post api call
}
struct Post: Codable, Identifiable {
   var id: Int
   var title: String
   var content: String
   // other properties
}
到目前为止,我看到人们只要返回到包含数据列表的视图就重新获取数据,但是该解决方案对我来说并不真正有效,因为我的数据是分页的,并且在重新获取时,它只是获取第一个页面并将用户带回其提要的顶部。我想到的两种可能的解决方案是,关于帖子,在所有视图之间使用一个共享视图模型,或者不将帖子本身存储在父视图模型中,而是存储子视图模型的列表。

谢谢!

rest swiftui mvvm ios16
2个回答
0
投票
通常你会这样做:

class PostUpdateView : View { let postID: UUID @State var post: Post? var body: some View { Text(post.title ?? "Loading...") .task(id: postID){ if postID == post?.id { return } // prevent re-downloading on re-appear post = await fetchPost(id: postID) } } }
最好尽可能避免在 Swift/SwiftUI 中使用类,因为它会导致一致性错误,任务会为你管理一个对象并具有正确的行为,在出现时初始化,在消失时取消和取消初始化等,而你自己很难做到这一点.


0
投票
通常,当我需要在不同视图之间共享数据时,我会将这些数据放入数据存储或聚合模型中。如下图所示:

class CatalogStore: ObservableObject { private var storeHTTPClient: StoreHTTPClient init(storeHTTPClient: StoreHTTPClient) { self.storeHTTPClient = storeHTTPClient } @Published var products: [Product] = [] @Published var categories: [Category] = [] func addProduct(_ product: Product) async throws { try await storeHTTPClient.addProduct(product) } func populateProducts() async throws { self.products = try await storeHTTPClient.loadProducts() } }
现在,我可以将 CatalogStore 的实例注入到 enviromentObject 中并从所有视图访问它。

© www.soinside.com 2019 - 2024. All rights reserved.