Bỏ qua để đến nội dung

URLSession

func fetchData() async throws -> [User] {
let url = URL(string: "https://api.example.com/users")!
let (data, _) = try await URLSession.shared.data(from: url)
return try JSONDecoder().decode([User].self, from: data)
}
func createUser(user: User) async throws {
var request = URLRequest(url: URL(string: "https://api.example.com/users")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONEncoder().encode(user)
let (_, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 201 else {
throw NetworkError.invalidResponse
}
}
@MainActor
class UsersViewModel: ObservableObject {
@Published var users: [User] = []
@Published var isLoading = false
@Published var error: Error?
func loadUsers() async {
isLoading = true
do {
let url = URL(string: "https://api.example.com/users")!
let (data, _) = try await URLSession.shared.data(from: url)
users = try JSONDecoder().decode([User].self, from: data)
} catch {
self.error = error
}
isLoading = false
}
}
struct UsersView: View {
@StateObject var viewModel = UsersViewModel()
var body: some View {
Group {
if viewModel.isLoading {
ProgressView()
} else {
List(viewModel.users) { user in
Text(user.name)
}
}
}
.task {
await viewModel.loadUsers()
}
}
}

  • Dùng async/await cho network calls
  • @MainActor cho ViewModel update UI
  • .task modifier trong View
  • Always handle errors