【问题标题】:Swift IOS Failed to access json array data using CodableSwift IOS 无法使用 Codable 访问 json 数组数据
【发布时间】:2019-12-04 18:20:56
【问题描述】:

如何使用 Codable 访问 JSON。这是我的示例 json。

{
    "status": "success",
    "message": "Data received successfully",
    "course": {
        "id": 1,
        "description": "something",
        "name": "ielts",
        "attachments": [
            {
                "id": 809,
                "attachment": "https:--",
                "file_name": "syllabus.pdf",
                "description": "course",

            },
            {
                "id": 809,
                "attachment": "https:--",
                "file_name": "syllabus.pdf",
                "description": "course",
            }]
        "upcased_name": "IELTS"
     }
}

这是我的代码。

struct ResponseObject: Codable {
    let course: [Course]
}

struct Course: Codable {
    let id: Int
    let name: String
    let description: String
    let attachments: [Attachments]
}

struct Attachments: Codable {
    let id: Int
    let attachment: String
    let file_name: String
    let description: String
    let about: String
}

var course: [Course] = []

这是我的 api 调用。

func fetchUserData() {

    let headers: HTTPHeaders = [
        "Authorization": "Token token="+UserDefaults.standard.string(forKey: "auth_token")!,
        "Accept": "application/json"
    ]
    let params = ["course_id" : "1"] as [String : AnyObject]
    self.showSpinner("Loading...", "Please wait!!")
    DispatchQueue.global(qos: .background).async {
        AF.request(SMAConstants.courses_get_course_details , parameters: params, headers:headers ).responseDecodable(of: ResponseObject.self, decoder: self.decoder) { response in

            DispatchQueue.main.async {
                self.hideSpinner()
                guard let value = response.value else {
                    print(response.error ?? "Unknown error")
                    return
                }

                self.course = value.course
            }
        }
    }
}

}

我收到以下错误。

responseSerializationFailed(原因: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(错误: Swift.DecodingError.typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "course", intValue: nil)], debugDescription: "预计解码 数组,但找到了字典。”,基础错误:无))))

【问题讨论】:

  • 阅读错误信息。 course 的值不是数组,而是字典(单个对象)。而且Attachment中没有about
  • 您应该测试较小的代码片段;例如,在这里,当您进行 API 调用时,您会发现您的 Codable 内容已损坏。如果相反,例如,您在项目中包含一些测试 JSON,然后通过从包中加载它来对其进行解码,那么一旦您确定可以继续进行 API 调用,这将非常有帮助。

标签: json swift alamofire codable


【解决方案1】:

您的模型对象与 JSON 结构不匹配。试试这个:

struct ResponseObject: Codable {
    let status, message: String
    let course: Course
}

struct Course: Codable {
    let id: Int
    let courseDescription, name: String
    let attachments: [Attachment]
    let upcasedName: String

    enum CodingKeys: String, CodingKey {
        case id
        case courseDescription = "description"
        case name, attachments
        case upcasedName = "upcased_name"
    }
}

struct Attachment: Codable {
    let id: Int
    let attachment, fileName, attachmentDescription: String

    enum CodingKeys: String, CodingKey {
        case id, attachment
        case fileName = "file_name"
        case attachmentDescription = "description"
    }
}

要使用普通的 Swift 和 Foundation 下载和解析它,请使用如下代码:

let url = URL(string: SMAConstants.courses_get_course_details)!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
    if let error = error {
        print(error)
        return
    }

    if let data = data {
      do {
        let response = try JSONDecoder().decode(ResponseObject.self, from: data)
        // access your data here
      } catch {
         print(error)
      }
    }
}
task.resume()

【讨论】:

  • 我试过我得到这个错误。 responseSerializationFailed(原因: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(错误: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "file_name", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "course", intValue: nil), CodingKeys(stringValue: "attachments", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"file_name\" , intValue: nil) (\"file_name\").", underlyingError: nil))))
  • 错误信息非常准确:您的课程附件不包含“file_name”。将fileName 属性设为可选以处理这种情况。
  • 你能告诉我如何在 Alamofire 请求中使用这些值吗?
  • 我要尝试返回 attachments.count 但它不起作用,以及如何将它用于 tableview 单元格。
  • 获取计数应该像responseObject.course.attachments.count 一样简单。我还建议不要为此使用像 Alamofire 这样的大型库,因为只需几行简单的 Swift 代码和 Foundation 工具就可以完成这项工作。将数据放入 tableview 是完全不同的事情,应该在一个单独的问题中提出,一旦您完成了此处众多且现成的教程和问题之一。
猜你喜欢
  • 2018-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
  • 1970-01-01
  • 2020-10-12
  • 2021-12-07
相关资源
最近更新 更多