像Instagram/X这样的应用在SwiftUI中如何实现跨不同信息流的帖子状态(如点赞)同步?

编程语言 2026-07-07

我在尝试理解在SwiftUI中使用新的Observation框架实现共享帖子状态的正确架构。

我有一个简单的例子,其中 ContentViewSavedView 都显示 PostView

@Observable class Post {
    var id: Int
    var content: String
    var title: String
    var isLiked: Bool = false

    init(id: Int, content: String, title: String, isLiked: Bool) {
        self.id = id
        self.content = content
        self.title = title
        self.isLiked = isLiked
    }

    func toggleLike() {
        isLiked.toggle()
    }
}


struct PostView: View {
     var post: Post

    var body: some View {
        HStack {
            Text(post.title)
            Text(post.content)
            Spacer()
            Button(post.isLiked ? "Liked" : "Like") {
                post.toggleLike()
            }
        }
    }
}

ContentView

struct ContentView: View {
    @State private var posts: [Post] = []

    var body: some View {
        List(posts, id: \.id) { post in
            PostView(post: post)
        }
        .task {
            if posts.isEmpty {
                let examplePost = Post(
                    id: 1,
                    content: "examplecontent",
                    title: "exampletitle",
                    isLiked: false
                )
                posts.append(examplePost)
            }
        }
    }
}

SavedView

struct SavedView: View {
    @State private var posts: [Post] = []

    var body: some View {
        List(posts, id: \.id) { post in
            PostView(post: post)
        }
        .task {
            if posts.isEmpty {
                let examplePost = Post(
                    id: 1,
                    content: "examplecontent",
                    title: "exampletitle",
                    isLiked: false
                )
                posts.append(examplePost)
            }
        }
    }
}

如果我在 ContentView 点赞,SavedView 中的同一篇帖子仍然显示为未点赞。

我理解在这个示例中,每个视图都创建了自己的 Post 实例,因此它们并没有真正共享同一个对象。

我的问题更多是关于架构:

  • 实际应用中通常如何解决?
  • 像Instagram或 X(Twitter)这样的应用是否为每条帖子维护一个单一的真实数据源(Single Source of Truth)?
  • 常见的做法是否是有一个中央存储/仓库(类似Redux/TCA),让每个屏幕通过ID引用同一个 Post 对象?
  • 还是在用户在屏幕之间导航时重新获取数据?
  • 结合SwiftUI的新Observation框架,什么样的架构算是惯用的?

我对大型社交应用是如何处理这个问题感兴趣,而不仅仅是修复这个示例。

解决方案

一些应用可能按屏幕逐个获取,一些会将数据加载到一个中央存储中,另一些则加载到一个会缓存到磁盘的中央存储中。

要将加载从基于视图迁移到基于存储,请移除 @State var posts.task,改为创建一个 @Observable class PostStore,并在其初始化时加载。要让存储成为中心位置,如果你在撰写本文时使用的是Xcode 27(处于测试版),你可以使用 @State var postsStore,但如果版本较低,则需要让该类符合 ObservableObject 并使用 @StateObject,或使用fileprivate全局变量或单例。

你需要在初始化时获取帖子(将JSON或轻量级自动解码的结构转换为重量级的Post对象,消除重复项),并在从服务器接收到推送通知、定时器触发或应用生命周期通知时进行更新。然后你需要监控所有唯一的 Post 对象的变更,在一个延迟/合并的函数(或通过生命周期通知和后台任务)中将变更发送到服务器。

顺便说一句,当你的模型是中央存储中的一个对象,例如你的 Post 类时,你应该在 List 中使用 \.self 作为 id,也就是通过指针来标识它。你也可以使其符合 Identifiable 并使用 var id: ObjectIdentifier { ObjectIdentifier(self) }

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章