Swift 中的网络管理器

问题描述 投票:0回答:1

我正在尝试创建一个 CRM 应用程序,为此我在树莓派上创建了一个数据库,并使用 PHP 在 url 上创建 JSON 结果。

现在我已经在 swift 中创建了以下网络管理器,但是 catch 末尾的 invalidData 错误不断被抛出。我做错了什么?

import Foundation

final class NetworkManager {
    static let shared = NetworkManager()
    static let baseURL = ""
    private let buyersURL = baseURL + ""
    
    private init(){}
    
    func getBuyers(completed: @escaping (Result<[Buyer], CRMError>) -> Void) {
        guard let url = URL(string: buyersURL) else {
            completed(.failure(.invalidURL))
            return
        }
        let task = URLSession.shared.dataTask(with: URLRequest(url: url)) { data, response, error in
            if let _ = error {
                completed(.failure(.unableToComplete))
                return
            }
            
            guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
                completed(.failure(.invalidResponse))
                return
            }
            
            guard let data = data else {
                completed(.failure(.invalidData))
                return
            }
            
            do {
                let decoder = JSONDecoder()
                let decodedResponse = try decoder.decode(BuyerResponse.self, from: data)
                completed(.success(decodedResponse.request))
            }  catch {
                completed(.failure(.invalidData))
            }
        }
        task.resume()
    }
}

以下是URL上JSON的结果

以下是我的买家结构:

import Foundation

struct Buyer: Codable, Identifiable, Hashable{
    let id: Int
    let user_id: Int
    let name: String
    let email: String
    let country: String
    let phone: String
    let second_phone: String
    let whishes: String
    let budget: String
    let timing: String
    let fase: String
    let media: String
    let plans: String
    let extra: String
    let hot: Int
}

struct BuyerResponse : Codable {
    let request: [Buyer]
}

这就是我所谓的“吸引买家”的视图:

struct BuyersView: View {
    @StateObject var viewModel = BuyersViewModel()

    @State var path = NavigationPath()
    
    @State private var buyers: [Buyer] = []
    
    var body: some View {
        NavigationStack(path: $path) {
            VStack{
                CategoryView(categories: viewModel.fases, currentSelection: $viewModel.currentFase)
                HStack{
                    Spacer()
                    NavigationLink("Add buyer", value: 0)
                        .padding()
                }
                List(buyers){ buyer in
                    BuyerCellView(buyer: buyer)
                }
            }
//            .navigationDestination(for: Int.self) { _ in
//                AddBuyerView(path: $path, fases: viewModel.fases, medias: $viewModel.media)
//            }.navigationDestination(for: Buyer.self) { buyer in
//                BuyerDetailView(buyer: buyer)
//            }
        }.onAppear{
             getBuyers()
        }
    }
    
    func getBuyers() {
        NetworkManager.shared.getBuyers { result in
            DispatchQueue.main.async {
                switch result {
                case .success(let buyers):
                    self.buyers = buyers
                case .failure(let error):
                    print(error.localizedDescription)
                }
            }
        }
    }
}

我检查了 JSON 上的变量和 Buyer 的结构是否相同,但错误不断发生,我只是希望变量 Buyers 从 JSON 返回一个 Buyers 列表。

我按照 https://www.youtube.com/watch?v=b1oC7sLIgpI&t=22362s 的教程学习了大约 6 小时的视频

感谢您提前提供帮助

json swift database swiftui networkmanager
1个回答
0
投票

BuyerResponse
里面你说JSON应该是这样的:

{ request: [{buyer 1 properties}, {buyer 2 properties}] }

但是从你的截图来看,响应看起来像这样:

    [{buyer 1 properties}, {buyer 2 properties}]

在 PHP 脚本中,您应该调整响应,以便在列表开始之前得到

request: 
。这应该可以解决问题。

另一种方法是在此处更改该行

let decodedResponse = try decoder.decode(BuyerResponse.self, from: data)

let decodedResponse = try decoder.decode([Buyer].self, from: data)

这样你就可以告诉解码器它正在获取一个

Buyer
的列表,周围没有任何内容。

通常,如果在该位置出现错误,则意味着您收到的数据与您指定的数据结构不匹配。

解决这个问题的一个好方法是创建一个只有一个属性的模型结构并检查它是否有效。然后添加另一个属性等。如果不起作用:打印您收到的错误,这将告诉您 JSON 的哪一行出现了意外情况。

© www.soinside.com 2019 - 2024. All rights reserved.