0

I create a very simple json data for practice, but it always decode error when JSONDecoder().decode. I try some way to modify my struct, but all gets same error(prints "error0"). The code is at below.

struct ss : Codable {
    var a : String
    var b : String
}


let js = "[{\"a\":\"1\",\"b\":\"2\"},{\"c\":\"3\",\"d\":\"4\"}]"
let data = js.data(using: .utf8)

let a = [ss].self
do {
    if let s = try? JSONDecoder().decode(a, from : data!) {
        print(s[0].a)
    }else{
        print("error0")
    }
}catch{
    print("error1")
}
6
  • 1
    Catch the error. There is a try that you don't listen to. And print the caught error. Commented Jan 3, 2019 at 9:33
  • It should say that there is no value found for key "a". That's because on the second dictionary, the keys are "c" and "d", not "a" and "b". Commented Jan 3, 2019 at 9:34
  • Larme: I edit the code, tks Commented Jan 3, 2019 at 9:38
  • Your should fix the JSON. the second item in the JSON array does not have the a and b properties. Or you can make the properties optional and will be nil. Commented Jan 3, 2019 at 9:42
  • print("error1"): No, do print("error1: \(error)"). There is an error object that can have information, usefull information and can differ. So read it, no "error1" only. Commented Jan 3, 2019 at 9:49

2 Answers 2

3

There is a problem with your JSON replace

let js = "[{\"a\":\"1\",\"b\":\"2\"},{\"c\":\"3\",\"d\":\"4\"}]"

with

let js = "[{\"a\":\"1\",\"b\":\"2\"},{\"a\":\"3\",\"b\":\"4\"}]"

The other dictionary don't have keys a and b and that's why JSONDecoder is not able to decode Now your update code will be:

struct ss : Codable {
    var a : String
    var b : String
}


let js = "[{\"a\":\"1\",\"b\":\"2\"},{\"a\":\"3\",\"b\":\"4\"}]"
let data = js.data(using: .utf8)

let a = [ss].self

do {
    let jsonDecoder = JSONDecoder()
    let s = try jsonDecoder.decode(a, from: data!)
    print(s[0].a) //"1\n"
} catch {
    print(error)
}

PS: As @Milander suggested If you don't want to fix JSON you can make optional properties in your Struct like

struct ss : Codable {
    let a, b, c, d: String?
}
Sign up to request clarification or add additional context in comments.

1 Comment

Happy to help you!!
0

You can define additional keys like below:

No optional No replacement

struct ss : Codable {
    var a : String
    var b : String

    init(from decoder: Decoder) throws {
        if let con = try? decoder.container(keyedBy: CodingKeys.self), let a = try? con.decode(String.self, forKey: .a), let b = try? con.decode(String.self, forKey: .b) {
            self.a = a
            self.b = b
        } else if let con = try? decoder.container(keyedBy: AdditionalInfoKeys.self), let c = try? con.decode(String.self, forKey: .c), let d = try? con.decode(String.self, forKey: .d) {
            a = c
            b = d
        } else {
            throw NSError(domain: "Decoding error", code: 123, userInfo: nil)
        }
    }

    enum AdditionalInfoKeys: String, CodingKey {
        case c, d
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.