Swift IOS 无法使用 Codable 访问 json 数组数据

Posted

技术标签:

【中文标题】Swift IOS 无法使用 Codable 访问 json 数组数据【英文标题】:Swift IOS Failed to access json array data using Codable 【发布时间】: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 调用,这将非常有帮助。 【参考方案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 是完全不同的事情,应该在一个单独的问题中提出,一旦您完成了此处众多且现成的教程和问题之一。

以上是关于Swift IOS 无法使用 Codable 访问 json 数组数据的主要内容,如果未能解决你的问题,请参考以下文章