swift JSON数据没有打印到Xcode控制台,也不会显示在我的一个选项卡视图上

pvcm50d1  于 5个月前  发布在  Swift
关注(0)|答案(1)|浏览(69)

我试图从URL解码JSON文件;我最初遇到了问题。我的产品数组没有接收JSON数据;我的代码如下。

import SwiftUI
import SDWebImageSwiftUI

class DataManager: ObservableObject {
    struct Returned: Decodable {
        let product: [products]
    }

    @Published var productsArray: [products] = []

    func fetchData(completion: @escaping () -> Void) {
        guard let url = URL(string: "https://compassjobsapp.net/DummyJSONData.json") else {
            print("Invalid URL")
            completion()
            return
        }

        URLSession.shared.dataTask(with: url) { data, _, error in
            if let error = error {
                print("Network error: \(error)")
                completion()
                return
            }

            if let data = data {
                    print("Received Data: \(String(data: data, encoding: .utf8) ?? "Unable   to convert data to string")")
                do {
                    let decodedData = try JSONDecoder().decode(Returned.self, from: data)
                    DispatchQueue.main.async {
                        self.productsArray = decodedData.product
                        print("Decoded Data: \(decodedData)")
                        print("Products Array: \(self.productsArray)")
                    }
                    print("Decoded Data: \(decodedData)")
                    completion()
                } catch {
                    print("Error decoding JSON: \(error)")
                    completion()
                        
                }
            }
        }.resume()
    }
}

struct ProductListView: View {
    @ObservedObject private var dataManager = DataManager()

    var body: some View {
        NavigationView {
            if dataManager.productsArray.isEmpty {
                Text("No products available")
            } else {
                List(dataManager.productsArray) { products in
                    NavigationLink(destination: ProductDetailView(product: products)) {
                        VStack(alignment: .leading, spacing: 8) {
                            WebImage(url: URL(string: products.thumbnail))
                                .resizable()
                                .scaledToFit()
                                .frame(height: 150)
                                .cornerRadius(8)

                            Text(products.title)
                                .font(.headline)
                                .foregroundColor(.primary)

                            Text("Price: $\(String(format: "%.2f", products.price))")
                                .font(.subheadline)
                                .foregroundColor(.secondary)
                        }
                        .padding(10)
                    }
                }
                .navigationTitle("Products")
                .onAppear {
                    dataManager.fetchData {
                        print("Products Array: \(dataManager.productsArray)")
                        // Print the products array to the console
                        print(dataManager.productsArray)
                    }
                }
            }
        }
    }
}

struct ProductDetailView: View {
    let product: products

    var body: some View {
        Text("Product Detail View")
    }
}

字符串
我尝试在代码的所有地方使用print语句调试代码,并使用控制台日志进行调试。不,我创建的一个print统计数据指向Xcode顾问。我的iOS模拟器显示标题为“无可用产品”的选项卡。
我哪里错了?

zf2sa74q

zf2sa74q1#

尝试这种方法,将.onAppear{...}附加到NavigationStack(注意NavigationView已被弃用)。同时使用有效的Returned模型解码JSON数据,并将@StateObject用于dataManager
对我来说效果很好,使用MacOS 14.2,Xcode 15.1,在真实的iOS 17设备和MacCatalyst上测试。
您需要查阅API的文档,以确定ReturnedProduct的任何属性是否是可选的,并将?添加到这些属性中。
完整的工作代码:

struct ContentView: View {
    var body: some View {
        ProductListView()
    }
}

class DataManager: ObservableObject {
    
    @Published var productsArray: [Product] = []  // <--- here

    func fetchData(completion: @escaping () -> Void) {
        guard let url = URL(string: "https://compassjobsapp.net/DummyJSONData.json") else {
            print("Invalid URL")
            completion()
            return
        }

        URLSession.shared.dataTask(with: url) { data, _, error in
            if let error = error {
                print("Network error: \(error)")
                completion()
                return
            }

            if let data = data {
                    print("Received Data: \(String(data: data, encoding: .utf8) ?? "Unable   to convert data to string")")
                do {
                    let decodedData = try JSONDecoder().decode(Returned.self, from: data)
                    DispatchQueue.main.async {
                        self.productsArray = decodedData.products  // <--- here `s`
                        print("Decoded Data: \(decodedData)")
                        print("Products Array: \(self.productsArray)")
                    }
                    print("Decoded Data: \(decodedData)")
                    completion()
                } catch {
                    print("Error decoding JSON: \(error)")
                    completion()
                        
                }
            }
        }.resume()
    }
}

struct ProductListView: View {
    @StateObject private var dataManager = DataManager()  // <--- here

    var body: some View {
        NavigationStack {  // <--- here
            if dataManager.productsArray.isEmpty {
                Text("No products available")
            } else {
                List(dataManager.productsArray) { products in
                    NavigationLink(destination: ProductDetailView(product: products)) {
                        VStack(alignment: .leading, spacing: 8) {
                            // commented for my testing
//                            WebImage(url: URL(string: products.thumbnail))
//                                .resizable()
//                                .scaledToFit()
//                                .frame(height: 150)
//                                .cornerRadius(8)

                            Text(products.title)
                                .font(.headline)
                                .foregroundColor(.primary)

                            Text("Price: $\(String(format: "%.2f", products.price))")
                                .font(.subheadline)
                                .foregroundColor(.secondary)
                        }
                        .padding(10)
                    }
                }
                .navigationTitle("Products")
            }
        }
        .onAppear {  // <--- here
            dataManager.fetchData {
                print("Products Array: \(dataManager.productsArray)")
                // Print the products array to the console
                print(dataManager.productsArray)
            }
        }
    }
}

struct ProductDetailView: View {
    let product: Product  // <--- here

    var body: some View {
        Text("Product Detail View")
        Text(product.title)
    }
}

struct Returned: Codable {
    let products: [Product]   // <--- here, note `s`
    let total, skip, limit: Int
}

struct Product: Identifiable, Codable {  // <--- here
    let id: Int
    let title, description: String
    let price: Int
    let discountPercentage, rating: Double
    let stock: Int
    let brand, category: String
    let thumbnail: String
    let images: [String]
}

字符串

相关问题