1

I'm creating a SwiftUI flashcard app, and I have no problem using Codable and following the technique Apple demonstrated with their landmarks tutorial app for importing JSON data in order to create their array of objects.

However, two of my flashcard objects' properties don't need to be loaded from JSON, and I could minimize the text needed in the JSON file if I could initialize those values separately instead of loading them from JSON. The problem is I cannot get JSON data to load without an error unless it maps exactly to ALL the object's properties, even if the missing properties are hardcoded with values.

Here is my object model:

import SwiftUI

class Flashcard: Codable, Identifiable {
    let id: Int
    var status: Int
    let chapter: Int
    let question: String
    let answer: String
    let reference: String
}

Here is JSON that works:

[
  {
    "id": 1,
    "status": 0,
    "chapter": 1,
    "question": "This is the question",
    "answer": "This is the answer",
    "reference": "This is the reference"
  }
  //other card info repeated after with a comma separating each
]

Instead of having "id" and "status" listed unecessarily in the JSON, I would prefer to change the model to something like this:

import SwiftUI

class Flashcard: Codable, Identifiable {
    let id = UUID()
    var status: Int = 0

    //only load these from JSON:
    let chapter: Int
    let question: String
    let answer: String
    let reference: String
}

...and then I theoretically should be able to eliminate "id" and "status" from the JSON (but I can't). Is there a simple way to do this that prevents the error from JSON not mapping completely to the object?

  • https://stackoverflow.com/questions/46740160/swift-decodable-optional-key?rq=1 ? https://stackoverflow.com/questions/44575293/with-jsondecoder-in-swift-4-can-missing-keys-use-a-default-value-instead-of-hav ? – Larme Nov 07 '19 at 15:20

2 Answers2

0

Yes, you can do this by setting the coding keys on your Codable class. Just leave out the ones that you don't want to update from the json.

class Flashcard: Codable, Identifiable {
    let id = UUID()
    var status: Int = 0
    let chapter: Int
    let question: String
    let answer: String
    let reference: String

    enum CodingKeys: String, CodingKey {
        case chapter, question, answer, reference
    }
}

There is a great article by HackingWithSwift on Codable here

Andrew
  • 26,706
  • 9
  • 85
  • 101
0

you can use CodingKeys to define what fields to extract from the JSON.

class Flashcard: Codable, Identifiable {
    enum CodingKeys: CodingKey {
       case chapter
       case question
       case answer
       case reference
    }

    let id = UUID()
    var status: Int = 0

    //only load these from JSON:
    let chapter: Int
    let question: String
    let answer: String
    let reference: String
}

The docuemntation has a good explanation (for once) of this under `Encoding and Decoding Custom Types`
flanker
  • 3,840
  • 1
  • 12
  • 20