Home > Mobile >  JSON to dict with class
JSON to dict with class

Time:08-22

I decide some JSON and try to typecast it to a dictionary of String: classy and it fails. I have found that often the reason I have trouble doing something is because of a misunderstanding of how Swift works, so here is what I want to happen. Feel free to tell me that I am doing it wrong and if I do it this way all will be wonderful.

I want my data to live between runs of the app so I have to save the data to storage between runs. I have an object, data and associated code, and I have places where changes I make to a copy should reflect back to the original so it is a class. I have a bunch of these objects and most of the time I pick the one I want based on an id that is an integer. An array is not good since it would be a sparse array cause come ids are not used. I came up with a dictionary with a key of the id and data of the structure. I turned the key from an Int to a String, by changing the Int id to a String, cause converting a dictionary to JSON is MUCH easier for a key that is a string. I save the JSON string. When the app starts again I read the string in and convert the JSON string to Any. Then I typecast the result to the desired dictionary. This is where it fails. The cast does not work. In my Googling the samples I found said this should work.

Here is my code:

class Y: Codable, Hashable {
  var a: String = "c"
  static func ==(lhs: Y, rhs: Y) -> Bool {
    return lhs.a == rhs.a
  }
  func hash(into hasher: inout Hasher) {
      hasher.combine(a)
  }
}

struct ContentView: View {
  var body: some View {
    VStack {
      Button ("Error") {
        var y = Y()
        var yDict = [String: Y]()
        yDict["0"] = y
        do {
          let encodedData = try JSONEncoder().encode(yDict)
          let jsonString = String(data: encodedData, encoding: .utf8)
          let decoded = try JSONSerialization.jsonObject(with: encodedData, options: [])
          if let yyDictDec = decoded as? [String:Y] {
            print("yDict after decide")
            print (yyDictDec)
          }
        } catch {
          print(error.localizedDescription)
        }
        print("x")
      }
    }
  }
}

In this code the if yyDictDec = is failing, I think, cause the prints after it never happen. I can cast it as [String, Any] but I really need it to be my class.

My problem is in the convert JSON back to the dictionary. I feel I am missing something fairly simple.

CodePudding user response:

Don´t use JSONSerialization use JsonDecoder and decode it to the the type it was before encoding. e.g.:

let decoded = try JSONDecoder().decode([String: Y].self, from: encodedData)
  • Related