【问题标题】:Parse nested data from JSON using Codable使用 Codable 从 JSON 解析嵌套数据
【发布时间】:2020-02-12 12:27:55
【问题描述】:

我正在尝试从 JSON 响应中解析嵌套数据,但没有成功。以下是我到目前为止尝试的内容以及尝试解析的 json 响应。

// JSON

 {
"statusCode": 200,
"success": true,
"data": {
    "tDetail": [
        {
            "roleId": null,
            "id": 34,
            "userId": 126,
            "catId": null,
            "importId": null,
            "name": "My task from postman",
            "myday": 1,
            "important": 0,
            "completed": 0,
            "dateCreated": "2020-02-10T09:05:04.000Z",
            "dateModified": "2020-02-10T09:05:04.000Z"
        }
    ],
    "steps": [],
    "files": [],
}
}

//结构体

struct MyDayAndTaskDetails: Codable
{
let data : [MyTaskDetail]
}

struct MyTaskDetail : Codable {
let roleId, taskId, userId, catId, important, completed, recurring, myday : Int?
let repeatType, name, duedate, reminder, frequency, weekdays, notes, baseurl : String?
let steps : [Steps]
let files : [Files]

private enum CodingKeys: String, CodingKey {
       case taskId = "id"
       case userId = "userId"
    case roleId = "roleId"
    case catId = "catId"
    case myday = "myday"
       case name = "name"
       case notes = "notes"
       case duedate = "duedate"
       case reminder = "reminder"
       case recurring = "recurring"
       case repeatType = "repeatType"
       case important = "important"
       case completed = "completed"
    case frequency = "frequency"
    case weekdays = "weekdays"
    case baseurl = "baseurl"
    case steps = "Steps"
    case files = "Files"

   }
}

struct Steps : Codable {
let stepName : String?
let status, stepId : Int?

private enum CodingKeys: String, CodingKey {
       case stepName = "stepName"
       case status = "status"
       case stepId = "stepId"
   }
}

struct Files : Codable {
let fileName : String?

private enum CodingKeys: String, CodingKey {
       case fileName = "fileName"
   }
}

【问题讨论】:

    标签: json swift struct codable decodable


    【解决方案1】:

    你错过了一级

    struct MyDayAndTaskDetails: Codable {
        let data : Detail       
    }
    
    struct Detail: Codable {
         let tDetail: [MyTaskDetail]
         let steps : [Steps]
         let files : [Files]
    }
    

    等等

    【讨论】:

    • 我明白了,请确认步骤和文件是否正确?
    • @iPhone7 请仔细查看 JSON。您会立即看到steps/filesuserID 等在垂直方向上处于不同的水平。
    • @iPhone7 抱歉,我错过了这两个,但这并不是答案的重点。答案已更新
    • 嗨,在我问问题之前你能指导我吗:func getTypeAPI(urlString: String, header: HTTPHeaders, completion: @escaping (MyDayAndTaskDetails?) -> Void) {
    • 在上面的评论中,我们可以在运行时将结构的名称作为参数传递而不是在那里定义,因为否则我必须在调用 api 时为所有结构创建单独的函数。希望我把我的观点说清楚了。
    【解决方案2】:

    使用这个结构体,下面的结构体对于给定的 json 就足够了。如果您的 json 中有更多键,则可以将它们添加到各自的结构中。

    struct MyDayAndTaskDetails : Codable {
        let data : Task?
        let statusCode : Int?
        let success : Bool?
    }
    struct Task : Codable {
        let files : [Files]?
        let steps : [Steps]?
        let tDetail : [TDetail]?
    }
    
    
    struct TDetail : Codable {
        let catId : String?
        let completed : Int?
        let dateCreated : String?
        let dateModified : String?
        let id : Int?
        let importId : String?
        let important : Int?
        let myday : Int?
        let name : String?
        let roleId : String?
        let userId : Int?
    }
    
    struct Steps : Codable {
        let stepName : String?
        let status: Int?
        let  stepId : Int?
    }
    
    struct Files : Codable {
        let fileName : String?
    }
    

    并用

    解码数据
    let decoder = JSONDecoder()
    let response = try decoder.decode(MyDayAndTaskDetails.self, from: data)
    

    【讨论】:

    • 谢谢,告诉我一件事如果我使用 let 文件会有什么不同:[文件]?或让文件:[字符串]?哪个是正确的方法,因为当前空数组即将到来?
    • 这意味着您在从 json 解析数据后将无法更改文件的值。这并不意味着当它来自json时它不会解析数据。如果数据来了,它就会解析它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多