2

I have a Codable struct myObj:

public struct VIO: Codable {

    let id:Int?;
    ...
    var par1:Bool = false; //default to avoid error in parsing
    var par2:Bool = false;    
}

When I do receive JSON, I don't have par1 and par2 since these variables are optional. During parsing I get an error:keyNotFound(CodingKeys(stringValue: \"par1\", intValue: nil)

How to solve this?

AlexP
  • 449
  • 2
  • 9
  • 25

1 Answers1

3

If you have local variables you have to specify the CodingKeys

public struct VIO: Codable {

    private enum CodingKeys : String, CodingKey { case id }

    let id:Int?
    ...
    var par1:Bool = false
    var par2:Bool = false  

}

Edit:

If par1 and par2 should be also decoded optionally you have to write a custom initializer

  private enum CodingKeys : String, CodingKey { case id, par1, par2 }

   init(from decoder: Decoder) throws {
      let container = try decoder.container(keyedBy: CodingKeys.self)
      id = try container.decode(Int.self, forKey: .id)
      par1 = try container.decodeIfPresent(Bool.self, forKey: .par1)
      par2 = try container.decodeIfPresent(Bool.self, forKey: .par2)
  }

This is Swift: No trailing semicolons

vadian
  • 274,689
  • 30
  • 353
  • 361
  • so in my case I need to simply include `private enum CodingKeys : String, CodingKey { case par1 = false case par2 = false }` ? – AlexP Apr 07 '18 at 16:42
  • 2
    @AlexP No... what he showed *is your case.* The coding keys are usually inferred from the type's property names. Specifying the coding keys explicitly gives you a chance to omit `par1`, and `par2`, and just have `id`. – Alexander Apr 07 '18 at 16:42
  • this means in CodingKeys I shall put all variables that I am sure are present in JSON? – AlexP Apr 07 '18 at 16:43
  • 1
    You need to specify only the CodingKeys you want to decode. – vadian Apr 07 '18 at 16:44
  • I have a problem: now these values are never parsed even if present – AlexP Apr 07 '18 at 18:39
  • @AlexP Which values? – vadian Apr 07 '18 at 19:01
  • `par1` and `par2` , those that were not in CodingKeys. I always get them as `false` – AlexP Apr 07 '18 at 19:02
  • You wrote: *these variables are used only locally.* – vadian Apr 07 '18 at 19:03
  • Yeah you are right, I didn't consider one use-case. I parse everything to json and then retrieve. So they are really optional in both directions, but should be parsed as well – AlexP Apr 07 '18 at 19:09
  • Then write a custom initializer and use `decodeIfPresent` – vadian Apr 07 '18 at 19:10
  • could you please make an example as an answer? – AlexP Apr 07 '18 at 19:12
  • Thanks a lot. Last question it works for both decoder and encoder or for encoder I need another init()? – AlexP Apr 07 '18 at 19:30