在ViewModel中使用async/await获取数据
在SwiftUI中,使用async/await可以极大地简化异步数据获取的过程。通过将异步操作与ViewModel结合,你可以更清晰地管理数据流和UI更新。
1. 创建ViewModel
首先,你需要创建一个ViewModel类,遵循ObservableObject协议。这使得你的ViewModel能够被SwiftUI视图观察。
swift
import SwiftUI
import Combine
class DataViewModel: ObservableObject {
@Published var data: [String] = []
@Published var errorMessage: String?
func fetchData() async {
do {
let fetchedData = try await fetchFromNetwork()
DispatchQueue.main.async {
self.data = fetchedData
}
} catch {
DispatchQueue.main.async {
self.errorMessage = "数据获取失败: \(error.localizedDescription)"
}
}
}
private func fetchFromNetwork() async throws -> [String] {
// 模拟网络请求
let url = URL(string: "https://api.example.com/data")!
let (data, _) = try await URLSession.shared.data(from: url)
let decodedData = try JSONDecoder().decode([String].self, from: data)
return decodedData
}
}2. 在视图中使用ViewModel
在SwiftUI视图中,你可以使用@StateObject来实例化ViewModel,并在视图中调用fetchData方法。
swift
struct ContentView: View {
@StateObject private var viewModel = DataViewModel()
var body: some View {
VStack {
if let errorMessage = viewModel.errorMessage {
Text(errorMessage)
.foregroundColor(.red)
} else {
List(viewModel.data, id: \.self) { item in
Text(item)
}
}
}
.task {
await viewModel.fetchData()
}
}
}3. 处理UI更新
在上面的代码中,fetchData方法会在获取数据后更新data属性。由于data是@Published,SwiftUI会自动重新渲染视图。
- 错误处理:如果在获取数据时发生错误,
errorMessage会被更新,SwiftUI会显示错误信息。 - 异步任务:使用
.task修饰符可以在视图加载时自动调用异步方法。
4. 优化数据获取
为了提高性能,可以考虑使用Task和TaskGroup来并行处理多个网络请求。这样可以减少等待时间,提高用户体验。
swift
func fetchMultipleData() async {
await withTaskGroup(of: [String].self) { group in
for i in 1...5 {
group.addTask {
return try await fetchFromNetwork(for: i)
}
}
for await result in group {
self.data.append(contentsOf: result)
}
}
}通过这种方式,你可以在ViewModel中高效地管理异步数据获取,确保UI始终保持响应。使用async/await不仅使代码更简洁,还提高了可读性和可维护性。🎉