【问题标题】:Problem parsing JSON data from server Swift从服务器 Swift 解析 JSON 数据的问题
【发布时间】:2021-07-08 15:09:41
【问题描述】:

我正在尝试解析来自服务器的数据,但出现此错误:

failure(Swift.DecodingError.typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil)))

参数应作为对象数组以及响应对象传递。我不知道我应该在我的代码中更改什么,以便响应结构良好。 这是响应的样子:

[
  {
   'code' : number, 
   'error' => boolean, 
   'code_error' => number, 
   'data_error' => string, 
   'message' => 'Falta Campo requerido'
  }
]

这些是应该传递的参数:

[
   {
      'email' => 'required|string|email',
      'event_type' => 'required|string',
      'watermark' => 'required|string',
      'date' => 'required',
      'location' => 'required|string',
      'segment' => 'required',
      'time' => 'required',
      'country' => 'required',
      'city' => 'required'
    }
]

这就是我的代码的样子。

数据:

struct MarcaAguaResData: Codable {
    let code: Int
    let error: Bool
    let message: String
}

struct MarcaAguaErrorResponse: Decodable, LocalizedError {
    let code: Int
    let error: Bool
    let message: String
    let code_error: Int
    let data_error: String
}

服务器:

class MarcaAguaService {
    func marcaAgua(parameters: [String: Any],
                completion: @escaping (Result<MarcaAguaResData, Error>)-> Void) {
    
    let urlString =  baseUrl + "events"
    
    guard let url = URL(string: urlString) else {
        completion(.failure(NetworkingError.badUrl))
        return
    }
    
    var request = URLRequest(url: url)
    var components = URLComponents()
    var queryItems = [URLQueryItem]()
    
    for (key, value) in parameters {
        let queryItem = URLQueryItem(name: key, value: String(describing: value))
        queryItems.append(queryItem)
    }
    
    
    components.queryItems = queryItems
    
    let queryItemsData = components.query?.data(using: .utf8)
    
    request.httpBody = queryItemsData
    request.httpMethod = "POST"
    request.setValue("Bearer \(token_login)", forHTTPHeaderField: "Authorization")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    
    let session = URLSession.shared
    
    let task = session.dataTask(with: request) { (data, response, error) in
        DispatchQueue.main.async {
            guard let unwrappedResponse = response as? HTTPURLResponse else {
                completion(.failure(NetworkingError.badResponse))
                return
            }
            
            switch unwrappedResponse.statusCode {
            case 200 ..< 300:
                print("success")
            default:
                print("failure")
            }
            
            if let unwrappedError = error {
                completion(.failure(unwrappedError))
                return
            }
            
            if let unwrappedData = data {
                do{
                    let json = try JSONSerialization.jsonObject(with: unwrappedData, options: .allowFragments)
                    print("BBBB")
                    print(json)
                    
                    if let successRes = try? JSONDecoder().decode(MarcaAguaResData.self, from: unwrappedData){
                        completion(.success(successRes))
                    }else{
                      
                        let errorResponse = try JSONDecoder().decode(MarcaAguaErrorResponse.self, from: unwrappedData)
                        print("Error \(errorResponse)")
                        completion(.failure(errorResponse))
                    }
                }catch{
                    print("AAA")
                    completion(.failure(error))
                }
            }
        }
    }
    task.resume()
}
}

【问题讨论】:

  • decode(CodableStruct.self, 表示您希望在 JSON 的顶层有一个对象 CodableStructdecode([CodableStruct].self, 表示您希望在 JSON 的顶层有一个 CodableStruct 数组。你正在发送一个数组,所以你没有正确解码......
  • 旁注,您发送的queryItemsData 是表单或url 编码数据,而不是JSON?这很奇怪,因为你收到了 JSON,然后你输入了 content-type,JSON...
  • 你建议我做什么?
  • request.httpBody = try? JSONSerialization.data(withJSONObject: parameters)request.httpBody = try? JSONSerialization.data(withJSONObject: [parameters])(不清楚您是只发送一个对象还是一组对象)。对于您的解码修复,MarcaAguaErrorResponse.self -> [MarcaAguaErrorResponse].self` 可能是相同的成功差异:MarcaAguaResData.self => [MarcaAguaResData].self

标签: ios swift nshttpurlresponse


【解决方案1】:

[MarcaAguaResData].self 是一个数组,而不是 MarcaAguaResData.self 这是一个字典

 if let successRes = try? JSONDecoder().decode([MarcaAguaResData].self, from: unwrappedData){
   completion(.success(successRes))
 }else{
    let errorResponse = try JSONDecoder().decode([MarcaAguaErrorResponse].self, from: unwrappedData)
    print("Error \(errorResponse)")
    completion(.failure(errorResponse))
 }

completion: @escaping (Result<[MarcaAguaResData], Error>)-> Void)

【讨论】:

  • 仍然没有向服务器发送数据。这有帮助,但我不知道我是否在参数部分中遗漏了一些东西
  • print(json) 给出的答案与发送的数据无关
  • @Sh_Khan 请检查您的邮件
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2017-10-04
  • 1970-01-01
  • 2015-06-09
  • 1970-01-01
相关资源
最近更新 更多