Trying the trick that @azamsharp shared here and here
| Mocked | Real |
|---|---|
![]() |
![]() |
| import SwiftUI | |
| struct Post: Decodable, Identifiable { | |
| let id: Int | |
| let title: String | |
| } | |
| protocol HttpClientProtocol { | |
| func fetchPosts() async throws -> [Post] | |
| } | |
| class HttpClient: HttpClientProtocol { | |
| func fetchPosts() async throws -> [Post] { | |
| let url = URL(string: "https://jsonplaceholder.typicode.com/posts")! | |
| let (data, _) = try await URLSession.shared.data(from: url) | |
| return try JSONDecoder().decode([Post].self, from: data) | |
| } | |
| } | |
| class MockedHttpClient: HttpClientProtocol { | |
| func fetchPosts() async throws -> [Post]{ | |
| return [Post(id: 1, title: "Post #1"), Post(id: 2, title: "Post #2")] | |
| } | |
| } | |
| struct HttpClientEnvironmentKey: EnvironmentKey { | |
| static var defaultValue: HttpClientProtocol = HttpClient() | |
| } | |
| extension EnvironmentValues { | |
| var httpClient: (HttpClientProtocol) { | |
| get { self[HttpClientEnvironmentKey.self] } | |
| set { self[HttpClientEnvironmentKey.self] = newValue } | |
| } | |
| } | |
| struct ContentView: View { | |
| @Environment(\.httpClient) private var httpClient | |
| @State private var posts: [Post] = [] | |
| var body: some View { | |
| VStack { | |
| List(posts) { post in | |
| Text(post.title) | |
| }.task { | |
| do { | |
| posts = try await httpClient.fetchPosts() | |
| } catch { | |
| print(error.localizedDescription) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| #Preview { | |
| ContentView() | |
| .environment(\.httpClient, MockedHttpClient()) | |
| } |