SwiftUI架构疑问:直接从View调用NetworkModel是否合理?ViewModel是否有益?
SwiftUI架构疑问:无ViewModel方案是否可行?ViewModel的价值是什么?
我一直在研究SwiftUI架构,了解过MVVM、TCA、MVC等模式。目前正在开发一款需从JSON API获取数据并展示的App,参考Apple代码示例实现了相关内容,代码能正常运行,但我有React开发背景,习惯在组件仅使用私有本地状态时不额外做处理,因此未创建ViewModel。想请教:当前方案是否正确?ViewModel能为我带来哪些益处?
实现的代码
NetworkModel
class NetworkModel { func getPosts() async throws -> [Post] { let (data, _) = try await URLSession.shared.data(from: URL(string: "https://jsonplaceholder.typicode.com/posts")!) let posts = try JSONDecoder().decode([Post].self, from: data) return posts } }
Post.swift
struct Post: Decodable { let id: Int let title: String let body: String }
PostListView
struct PostListView: View { @State private var posts: [Post] = [] let networkModel = NetworkModel() var body: some View { List(posts, id: \.id) { post in Text(post.title) }.task { do { posts = try await networkModel.getPosts() } catch { print(error) } } } }
问题解答
当前方案是否正确?
你的方案是可行且正确的——对于这种简单的单页面数据展示场景,直接在View中处理异步请求、维护本地状态完全符合SwiftUI的设计逻辑,Apple官方也有不少类似的示例代码。
这里注意下你的PostListView原代码有个小疏漏:.task闭包中调用networkModel.getPosts()后没有把返回值赋值给posts状态,补上posts = try await networkModel.getPosts()才能正常渲染数据。
ViewModel能带来哪些益处?
当App复杂度提升时,ViewModel的价值会逐渐凸显,主要有这些核心优势:
- 逻辑解耦:把数据请求、状态处理(比如加载状态、错误状态)、数据转换(比如将原始Post数据处理为适合展示的格式)从View中剥离,让View只专注于UI渲染,代码结构更清晰。
- 状态共享:如果多个View需要使用同一份数据(比如Post列表页和详情页共享数据),ViewModel可以作为单一数据源,避免重复请求和状态不一致的问题。
- 可测试性:ViewModel中的业务逻辑可以单独编写单元测试,不需要依赖UI组件,测试起来更简单高效。
- 生命周期适配:通过
ObservableObject绑定View的生命周期,能避免View重建时重复初始化网络请求等资源,提升性能。 - 状态扩展便捷:后续如果要添加加载动画、错误提示、下拉刷新等功能,ViewModel可以统一管理
isLoading、errorMessage这类状态,View只需要根据状态更新UI即可,不用在View层堆砌复杂逻辑。
内容的提问来源于stack exchange,提问作者user19037628
相关产品推荐
相关产品推荐

