Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.7k views
in Technique[技术] by (71.8m points)

json - Swift Codable expected to decode Dictionary<String, Any>but found a string/data instead

I have been working with the Codable protocol

Here is my JSON file :

    {  
   "Adress":[  

   ],
   "Object":[  
      {  
         "next-date":"2017-10-30T11:00:00Z",
         "text-sample":"Some text",
         "image-path":[  
            "photo1.png",
            "photo2.png"
         ],
         "email":"[email protected]",
         "id":"27"
      },
      {  
         "next-date":"2017-10-30T09:00:00Z",
         "text-sample":"Test Test",
         "image-path":[  
            "image1.png"
         ],
         "email":"[email protected]",
         "id":"28"
      }
   ]
}

I only have to focus on the Object array, and the "image-path" array can contain 0, 1, or 2 strings.

So here is my implementation:

struct Result: Codable {
    let Object: [MyObject]
}

struct MyObject: Codable {

    let date: String
    let text: String
    let image: [String]
    let email: String
    let id: String

    enum CodingKeys: String, CodingKey {
        case date = "next-date"
        case text = "text-sample"
        case image = "image-path"
        case email = "email"
        case id = "id"
    }

    init() {
        self.date = ""
        self.text = ""
        self.image = []
        self.email = ""
        self.id = ""
    }
}

I call it from my service class after requesting and getting the JSON data this way:

if let data = response.data {
                let decoder = JSONDecoder()
                let result = try! decoder.decode(Result, from: data)
                dump(result.Object)
            }

Everything is working except the [String] for the image property

But it can't compile, or I get an "Expected to decode..." error.

How should I handle the nil/no data scenario?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I have made a small change in your MyObject struct, i.e.,

1. Marked all properties as optionals

2. Removed init() (I don't think there is any requirement of init() here.)

3. Use Result.self instead of Result in decoder.decode(...) method

struct MyObject: Codable
{
    let date: String?
    let text: String?
    let image: [String]?
    let email: String?
    let id: String?

    enum CodingKeys: String, CodingKey
    {
        case date = "next-date"
        case text = "text-sample"
        case image = "image-path"
        case email = "email"
        case id = "id"
    }
}

To test the above, I have used the below code and it is working fine.

    let jsonString = """
        {"Adress": [],
        "Object": [{"next-date": "2017-10-30T11:00:00Z",
        "text-sample": "Some text",
        "image-path": ["photo1.png", "photo2.png"],
        "email": "[email protected]",
        "id": "27"},
      {"next-date": "2017-10-30T09:00:00Z",
       "text-sample": "Test Test",
       "image-path": ["image1.png"],
       "email": "[email protected]",
       "id": "28"}
       ]
        }
    """
    if let data = jsonString.data(using: .utf8)
    {
        let decoder = JSONDecoder()
        let result = try? decoder.decode(Result.self, from: data) //Use Result.self here
        print(result)
    }

This is the result value that I am getting:

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...