JSONDecoder로 데이터를 디코딩할 때 에러가 없지만 디코딩된 데이터가 비어있는 경우가 있을 수 있습니다
Decoding 할 데이터
우선 다음과 같은 데이터 모델을 Decoding 하려고 시도하였습니다, 하지만 끊임없이 문제가 발생하였습니다.
@Model
class ExerciseRecordContainer: Identifiable, Decodable {
enum CodingKeys: CodingKey {
case startDate
case endDate
case totalTime
case routineName
}
var startDate: Date = Date()
var endDate: Date = Date()
var totalTime: Int = 0
var routineName: String = ""
var exerciseRecordModel: [ExerciseRecordModel] = []
init(startDate: Date, endDate: Date, totalTime: Int, routineName: String, exerciseRecordModel: [ExerciseRecordModel]) {
self.startDate = startDate
self.endDate = endDate
self.totalTime = totalTime
self.routineName = routineName
self.exerciseRecordModel = exerciseRecordModel
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
startDate = try container.decode(Date.self, forKey: .startDate)
endDate = try container.decode(Date.self, forKey: .endDate)
totalTime = try container.decode(Int.self, forKey: .totalTime)
routineName = try container.decode(String.self, forKey: .routineName)
}
}
class ExerciseRecordModel: Codable, Identifiable {
var id = UUID()
var exerciseName: String = "달리기"
var part: [ExercisePart] = []
var tool: ExerciseTool = ExerciseTool.bodyWeight
var set: Int = 0
var count: [Int] = []
var kg: [Int] = []
var done: [Bool] = []
init(exerciseName: String, part: [ExercisePart], tool: ExerciseTool, set: Int, count: [Int], kg: [Int], done: [Bool]) {
self.exerciseName = exerciseName
self.part = part
self.tool = tool
self.set = set
self.count = count
self.kg = kg
self.done = done
}
}
다음으로는 시도한 디코딩 코드입니다. 분명 ExerciseRecordContainer로 디코딩은 문제가 없이 잘 되었습니다. 하지만 디코딩 하였으면 내부에 exerciseRecordModel에도 값이 채워져야 하는데 값을 지속적으로 nil을 반환하는 것과 do catch 문에서 에러도 발생하지 않는 것을 확인하였습니다.
{
"startDate": 20240507095452,
"endDate": 20240507095852,
"totalTime": 44,
"routineName": "ㅋㅋ 루틴",
"exerciseRecordModel": [
{
"id": "A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6",
"exerciseName": "스쿼트",
"part": ["quadriceps"],
"tool": "barbell",
"set": 3,
"count": [12, 10, 8],
"kg": [60, 70, 80],
"done": [true, true, false]
}
]
}
recordContainer = try JSONDecoder().decode(ExerciseRecordContainer.self, from: data)
수많은 시간을 들여 고생하여 결국 생각한 것은 아래서부터 차근차근 해결해보자 였습니다. ExerciseRecordContainer로 디코딩하기 전에 ExerciseRecordModel로 먼저 디코딩을 해보는 것입니다.
var test = try JSONDecoder().decode(ExerciseRecordModel.self, from: data)
do-catch 문으로 에러가 잡혔습니다, 에러는 part의 데이터 형식이 다르다는 것을 확인하였으며 아래처럼 고쳐주게 된다면 문제없이 성공적으로 디코딩이 가능해집니다.
{
"startDate": 20240507095452,
"endDate": 20240507095852,
"totalTime": 44,
"routineName": "루틴",
"exerciseRecordModel": [
{
"id": "8749fadd-3a9b-4d53-9250-fb32f98e57dd",
"exerciseName": "스쿼트",
"part": ["대퇴사두"],
"tool": "덤벨",
"set": 3,
"count": [12, 10, 8],
"kg": [60, 70, 80],
"done": [true, true, false]
}
]
}
하지만 그래도 nil로 값이 디코딩되는 것을 확인할 수 있었습니다. 결국 해결한 방법으로는 이 코드에 경우 required init(from decoder: Decoder)를 완전히 구현하지 않았기 때문에 발생한 에러였음을 확인할 수 있었습니다.
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
startDate = try container.decode(Date.self, forKey: .startDate)
endDate = try container.decode(Date.self, forKey: .endDate)
totalTime = try container.decode(Int.self, forKey: .totalTime)
routineName = try container.decode(String.self, forKey: .routineName)
}
@Model 메크로를 사용하여 디코딩하기 위해서는 디코딩할 값들을 모두 어떻게 디코딩할 것인지를 명시해야하는데 exerciseRecordModel은 명시되지 않았기 때문에 발생했었습니다. 고로 아래처럼 수정하면 성공입니다
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
startDate = try container.decode(Date.self, forKey: .startDate)
endDate = try container.decode(Date.self, forKey: .endDate)
totalTime = try container.decode(Int.self, forKey: .totalTime)
routineName = try container.decode(String.self, forKey: .routineName)
exerciseRecordModel = try container.decode([ExerciseRecordModel].self, forKey: .exerciseRecordModel)
}
'SwiftUI > 에러해결' 카테고리의 다른 글
SwiftUI - Observable 여러 뷰에서 데이터 업데이트 안됨 (0) | 2024.08.21 |
---|---|
SwiftUI - ChatGPT 에 이미지 전송 안됨 (0) | 2024.08.10 |
PhotosPicker 사진 회전되어 출력되는 현상 해결 (0) | 2024.07.10 |
SwiftData Fatal Error in ModelContainer.swift 에러 (0) | 2024.06.22 |
may be missing as an ancestor of this view 에러 (0) | 2024.03.16 |