Preview is not loading data from Mock Json

49 Views Asked by At

Here is my PostListView.

struct PostListView: View {

@StateObject private var viewModel = PostViewModel(service: PostService())

var body: some View {
    NavigationView {
        VStack {
            if viewModel.isLoading {
                ProgressView()
            } else if !viewModel.errorMessage.isEmpty {
                Text(viewModel.errorMessage)
            } else {
                List(viewModel.posts) { post in
                    VStack(alignment: .leading) {
                        Text(post.title)
                            .font(.headline)
                        Text(post.body)
                            .font(.subheadline)
                            .foregroundColor(.gray)
                    }
                }
            }
        }
        .navigationTitle("Posts")
    }
}

}


struct PostListView_Previews: PreviewProvider {
static var previews: some View {
    let viewModel = PostViewModel(service: MockPostService())
    return PostListView().environmentObject(viewModel)
}
}

Here is My ViewModel

class PostViewModel: ObservableObject {

@Published var posts: [PostModel] = []
@Published var isLoading: Bool = false
@Published var errorMessage: String = ""

private let service: ServiceProtocol

init(service: ServiceProtocol) {
    self.service = service
    Task {
        await fetchPosts()
    }
}

@MainActor func fetchPosts() async {

       isLoading = true
       await service.fetchData { [weak self] (result: Result<[PostModel], APIError>)in
           
           DispatchQueue.main.async {
               switch result {
                   
               case .success(let posts):
                   self?.posts = posts
                   
               case .failure(let error):
                   self?.errorMessage = "Failed to fetch posts: \(error.getErrorMessage())"

               }

               self?.isLoading = false
           }

       }
   }
}

Here is my

class MockPostService: ServiceProtocol {

func fetchData(completion: @escaping (Result<[PostModel], APIError>) -> Void) async{
    guard let jsonData = readJSONFromFile(named: "SamplePost") else {
        completion(.failure(.invalidData))
        return
    }
    
    do {
        let decoder = JSONDecoder()
        let sampleData = try decoder.decode([PostModel].self, from: jsonData)
        completion(.success(sampleData))
    } catch {
        print("Error decoding JSON data: \(error)")
        completion(.failure(.decodingError))
    }
}

func readJSONFromFile(named fileName: String) -> Data? {
    guard let filePath = Bundle.main.path(forResource: fileName, ofType: "json") else {
        print("Error: JSON file not found.")
        return nil
    }
    
    do {
        let data = try Data(contentsOf: URL(fileURLWithPath: filePath))
        return data
    } catch {
        print("Error reading JSON file: \(error)")
        return nil
    }
}

}

When I run this project It's working fine as expected. But the problem is in the preview. It also loads data from API, instead of Mcok Json.

For debugging purposes in PostListView, I replace the stateobject with a dummy JSON and run the project.

@StateObject private var viewModel = PostViewModel(service: MockPostService())

It's loading data from Mock JSON.

In summary, I want a preview that will load data from Mcok Json.

0

There are 0 best solutions below