Search code examples
iosswiftstructcodablecodingkey

Swift Key 'CodingKeys()' not found: No value associated with key CodingKeys() ("row")


"Key 'CodingKeys(stringValue: "row", intValue: nil)' not found: No value associated with key CodingKeys(stringValue: "row", intValue: nil) ("row"). codingPath: [CodingKeys(stringValue: "schoolInfo", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)] "

I am getting these errors

I'm doing API communication for school information

Here's the JSON response

{
    "schoolInfo": [
        {
            "head": [
                {
                    "list_total_count": 1
                },
                {
                    "RESULT": {
                        "CODE": "INFO-000",
                        "MESSAGE": "정상 처리되었습니다."
                    }
                }
            ]
        },
        {
            "row": [
                {
                    "ATPT_OFCDC_SC_CODE": "F10",
                    "ATPT_OFCDC_SC_NM": "광주광역시교육청",
                    "SD_SCHUL_CODE": "7401173",
                    "SCHUL_NM": "정암초등학교",
                    "ENG_SCHUL_NM": "Jeong-Am Elementary School",
                    "SCHUL_KND_SC_NM": "초등학교",
                    "LCTN_SC_NM": "광주광역시",
                    "JU_ORG_NM": "광주광역시서부교육지원청",
                    "FOND_SC_NM": "공립",
                    "ORG_RDNZC": "62254 ",
                    "ORG_RDNMA": "광주광역시 광산구 첨단과기로 104",
                    "ORG_RDNDA": "(월계동)",
                    "ORG_TELNO": "062-970-4104",
                    "HMPG_ADRES": "http://jungam.gen.es.kr",
                    "COEDU_SC_NM": "남여공학",
                    "ORG_FAXNO": "062-972-3949",
                    "HS_SC_NM": null,
                    "INDST_SPECL_CCCCL_EXST_YN": "N",
                    "HS_GNRL_BUSNS_SC_NM": "일반계",
                    "SPCLY_PURPS_HS_ORD_NM": null,
                    "ENE_BFE_SEHF_SC_NM": "전기",
                    "DGHT_SC_NM": "주간",
                    "FOND_YMD": "19960301",
                    "FOAS_MEMRD": "19961002",
                    "LOAD_DTM": "20230115"
                }
            ]
        }
    ]
}

Here's the struct

struct schoolResponse: Codable {
    let schoolInfo: [schoolRow]
}

struct schoolRow: Codable {
    let row: [schoolsInfo]
}

struct schoolsInfo: Codable {
    var schoolName: String
    var schoolCode: String
    var officeCode: String
    
    private enum CodingKeys: String, CodingKey {
        case schoolName = "SCHUL_NM"
        case schoolCode = "SD_SCHUL_CODE"
        case officeCode = "ATPT_OFCDC_SC_CODE"
    }
}

Here's the function

protocol SchoolInfoProtocol: AnyObject {
    var schoolData: PublishSubject<[schoolRow]> { get set }
}

class SchoolNameViewModel: BaseViewModel {
    weak var delegate: SchoolInfoProtocol?
    var schoolAddress: [schoolsInfo] = []
    
    func fetchSchoolName(schoolName: String) {
        let provider = MoyaProvider<SchoolNameAPI>()
        
        provider.request(.schools(schoolName: schoolName, apiKey: "e6f3e10be1b1426cbcfb2be62afff409")) { (result) in
            switch result {
            case .success(let response):
                let responseData = response.data
                do {
                    let decoded = try JSONDecoder().decode(schoolResponse.self, from: responseData).schoolInfo
//                    self.delegate?.schoolData.onNext(decoded)
                    print(decoded)
                } catch let DecodingError.dataCorrupted(context) {
                    print(context)
                } catch let DecodingError.keyNotFound(key, context) {
                    print("Key '\(key)' not found:", context.debugDescription)
                    print("codingPath:", context.codingPath)
                } catch let DecodingError.valueNotFound(value, context) {
                    print("Value '\(value)' not found:", context.debugDescription)
                    print("codingPath:", context.codingPath)
                } catch let DecodingError.typeMismatch(type, context)  {
                    print("Type '\(type)' mismatch:", context.debugDescription)
                    print("codingPath:", context.codingPath)
                } catch {
                    print("error: ", error)
                }
            case .failure(let error):
                print(error.localizedDescription)
                print("1")
            }
        }
    }
}

I want to solve this problem

I created a root model


Solution

  • Your structs don't match the JSON. Try this instead:

    struct SchoolResponse: Codable {
        let schoolInfo: [SchoolInfo]
    }
    
    struct SchoolInfo: Codable {
        let head: [Head]?
        let row: [Row]?
    }
    
    struct Head: Codable {
        let listTotalCount: Int?
        let result: Result?
    
        enum CodingKeys: String, CodingKey {
            case listTotalCount = "list_total_count"
            case result = "RESULT"
        }
    }
    
    struct Result: Codable {
        let code, message: String
    
        enum CodingKeys: String, CodingKey {
            case code = "CODE"
            case message = "MESSAGE"
        }
    }
    
    struct Row: Codable {
        let atptOfcdcScCode, atptOfcdcScNm, sdSchulCode, schulNm: String
        let engSchulNm, schulKndScNm, lctnScNm, juOrgNm: String
        let fondScNm, orgRdnzc, orgRdnma, orgRdnda: String
        let orgTelno: String
        let hmpgAdres: String
        let coeduScNm, orgFaxno: String
        let hsScNm: String?
        let indstSpeclCccclExstYn, hsGnrlBusnsScNm: String
        let spclyPurpsHsOrdNm: String?
        let eneBfeSehfScNm, dghtScNm, fondYmd, foasMemrd: String
        let loadDtm: String
    
        enum CodingKeys: String, CodingKey {
            case atptOfcdcScCode = "ATPT_OFCDC_SC_CODE"
            case atptOfcdcScNm = "ATPT_OFCDC_SC_NM"
            case sdSchulCode = "SD_SCHUL_CODE"
            case schulNm = "SCHUL_NM"
            case engSchulNm = "ENG_SCHUL_NM"
            case schulKndScNm = "SCHUL_KND_SC_NM"
            case lctnScNm = "LCTN_SC_NM"
            case juOrgNm = "JU_ORG_NM"
            case fondScNm = "FOND_SC_NM"
            case orgRdnzc = "ORG_RDNZC"
            case orgRdnma = "ORG_RDNMA"
            case orgRdnda = "ORG_RDNDA"
            case orgTelno = "ORG_TELNO"
            case hmpgAdres = "HMPG_ADRES"
            case coeduScNm = "COEDU_SC_NM"
            case orgFaxno = "ORG_FAXNO"
            case hsScNm = "HS_SC_NM"
            case indstSpeclCccclExstYn = "INDST_SPECL_CCCCL_EXST_YN"
            case hsGnrlBusnsScNm = "HS_GNRL_BUSNS_SC_NM"
            case spclyPurpsHsOrdNm = "SPCLY_PURPS_HS_ORD_NM"
            case eneBfeSehfScNm = "ENE_BFE_SEHF_SC_NM"
            case dghtScNm = "DGHT_SC_NM"
            case fondYmd = "FOND_YMD"
            case foasMemrd = "FOAS_MEMRD"
            case loadDtm = "LOAD_DTM"
        }
    }
    

    (remove or rename properties as needed)