如何使用Swift解决JSON可编码TypeMismatch解码错误

时间:2019-09-19 17:58:24

标签: ios json swift

我正在使用JSON方法获取Codable数据。在这里,在我的JSON响应中,大多数值都以String的形式接收,但有时却收到了Int。那时我遇到Decoding如下错误

  

TypeMismatch(Swift.String,Swift.DecodingError.Context(codingPath:   [CodingKeys(stringValue:“ data”,intValue:nil),   CodingKeys(stringValue:“ status”,intValue:nil)],debugDescription:   “预期对String进行解码,但找到了一个数字。”,   底层错误:nil))

可编码

// MARK: - Welcome
struct Welcome: Codable {
    let status: Bool
    let data: DataClass
}

// MARK: - DataClass
struct DataClass: Codable {
    let memberID, groupID, memberName, dataDescription: String
    let duedate, team, member: String
    let membergroup: JSONNull?
    let teams, category, junction, grouptype: String
    let typegroup, groupMethod, memberCD, checklist: String
    let refID, startDate, createdBy, createdDate: String
    let startedBy: JSONNull?
    let startedDate: String
    let submittedBy, submittedDate, completedBy: JSONNull?
    let completedDate, extendDate: String
    let editedBy: JSONNull?
    let editedDate: String
    let status: Int
    let autotask, isdelete, timestamp, assignedMember: String
    let teamName, gemID, gemName, ticketName: String
    let ticketTypeName, ableToDelete, assignedForMe, priorityFlag: String
    let taskTypeFlag: String
    let comments, notification, reminder: [JSONAny]
    let acceptOrDecline: String
    let availableStatus: [AvailableStatus]
    let editedUserName: String

    enum CodingKeys: String, CodingKey {
        case memberID = "member_id"
        case groupID = "group_id"
        case memberName = "member_name"
        case dataDescription = "description"
        case duedate, team, member, membergroup, teams, category, junction, grouptype, typegroup
        case groupMethod = "group_method"
        case memberCD = "member_cd"
        case checklist
        case refID = "ref_id"
        case startDate = "start_date"
        case createdBy = "created_by"
        case createdDate = "created_date"
        case startedBy = "started_by"
        case startedDate = "started_date"
        case submittedBy = "submitted_by"
        case submittedDate = "submitted_date"
        case completedBy = "completed_by"
        case completedDate = "completed_date"
        case extendDate = "extend_date"
        case editedBy = "edited_by"
        case editedDate = "edited_date"
        case status, autotask, isdelete, timestamp
        case assignedMember = "assigned_member"
        case teamName = "team_name"
        case gemID = "gem_id"
        case gemName = "gem_name"
        case ticketName = "ticket_name"
        case ticketTypeName = "ticket_type_name"
        case ableToDelete = "able_to_delete"
        case assignedForMe = "assigned_for_me"
        case priorityFlag = "priority_flag"
        case taskTypeFlag = "task_type_flag"
        case comments, notification, reminder
        case acceptOrDecline = "accept_or_decline"
        case availableStatus = "available_status"
        case editedUserName = "edited_user_name"
    }
}

// MARK: - AvailableStatus
struct AvailableStatus: Codable {
    let id: Int
    let name, displayName, icon: String

    enum CodingKeys: String, CodingKey {
        case id, name
        case displayName = "display_name"
        case icon
    }
}

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

// MARK: - Welcome
class Welcome: Codable {
    let status: Bool
    let data: DataClass
}

// MARK: - DataClass
class DataClass: Codable {
    let memberID, groupID, memberName, dataDescription: String
    let duedate, team, member: String
    let membergroup: JSONNull?
    let teams, category, junction, grouptype: String
    let typegroup, groupMethod, memberCD, checklist: String
    let refID, startDate, createdBy, createdDate: String
    let startedBy: JSONNull?
    let startedDate: String
    let submittedBy, submittedDate, completedBy: JSONNull?
    let completedDate, extendDate: String
    let editedBy: JSONNull?
    let editedDate: String
    let status: Int
    let autotask, isdelete, timestamp, assignedMember: String
    let teamName, gemID, gemName, ticketName: String
    let ticketTypeName, ableToDelete, assignedForMe, priorityFlag: String
    let taskTypeFlag: String
    let comments, notification, reminder: [JSONAny]
    let acceptOrDecline: String
    let availableStatus: [AvailableStatus]
    let editedUserName: String

    enum CodingKeys: String, CodingKey {
        case memberID = "member_id"
        case groupID = "group_id"
        case memberName = "member_name"
        case dataDescription = "description"
        case duedate, team, member, membergroup, teams, category, junction, grouptype, typegroup
        case groupMethod = "group_method"
        case memberCD = "member_cd"
        case checklist
        case refID = "ref_id"
        case startDate = "start_date"
        case createdBy = "created_by"
        case createdDate = "created_date"
        case startedBy = "started_by"
        case startedDate = "started_date"
        case submittedBy = "submitted_by"
        case submittedDate = "submitted_date"
        case completedBy = "completed_by"
        case completedDate = "completed_date"
        case extendDate = "extend_date"
        case editedBy = "edited_by"
        case editedDate = "edited_date"
        case status, autotask, isdelete, timestamp
        case assignedMember = "assigned_member"
        case teamName = "team_name"
        case gemID = "gem_id"
        case gemName = "gem_name"
        case ticketName = "ticket_name"
        case ticketTypeName = "ticket_type_name"
        case ableToDelete = "able_to_delete"
        case assignedForMe = "assigned_for_me"
        case priorityFlag = "priority_flag"
        case taskTypeFlag = "task_type_flag"
        case comments, notification, reminder
        case acceptOrDecline = "accept_or_decline"
        case availableStatus = "available_status"
        case editedUserName = "edited_user_name"
    }

    required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        memberID = try values.decodeIfPresent(String.self, forKey: .memberID)
        groupID = try values.decodeIfPresent(String.self, forKey: .groupID)
        //...... etc.
    }
}

// MARK: - AvailableStatus
class AvailableStatus: Codable {
    let id: Int
    let name, displayName, icon: String

    enum CodingKeys: String, CodingKey {
        case id, name
        case displayName = "display_name"
        case icon
    }

    required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decodeIfPresent(Int.self, forKey: .id)
        //...... etc.
    }
}