|
Hello, I'm slowly working through the milestone challenge for projects 10-12, and am having an issue with the JSONDecoder step of parsing the friendface.json file. I'm getting the following message when I try to decode the JSON contents:
I have the following structs in my project:
My ContentView is pretty simple, and includes a single @State var:
I modeled this process on the material discussed in day 49, but clearly, something is different about the data. Looking at the ITunes data, it formats the data differently by including a resultCount header. The friendface.json file does not have that. I'm not clear on where/why the decoding process is looking for a "users" key, or how to tell the decoder to skip over that and process the array items. I've tried distilling the code down by commenting out all but the id variable in the User struct, but I get the same results. Any thoughts on this would be sincerely appreciated. Thanks for taking the time to look at this! |
|
Mitchell battles the JSON demons!
You gave yourself a clue! Follow the clue! Where in your code do you mentions
Now, where in your code do you reference a
Now take a close look at the raw JSON data. But what you're trying to decode is an array of Response objects. The only contents of the This is NOT what you're trying to decode! This is important to understand. You are decoding ONE Think what you're trying to decode! The Instead try:
Come back and share your results. |
|
"Mitchell battles the JSON demons!" - That's about as accurate as it could be. With the suffix of "And he's losing!" would also be appropriate. Your solution was exactly what I needed, and I appreciate the clarification. Making the code change to an array of Users being returned corrects the issue, and I'm able to move forward. I really appreciate the assistance. During my initial troubleshooting, I had tried the following code:
When I tried that line, with the Response struct defined exactly as above, the JSON Decoder returned an error of: " error: typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil)) " Since Response effectively consists of a variable containing an array of Users, I am puzzled why the Decoder thinks it is trying to decode a Dictionary. Can you shed any light on why this approach also fails? (Those JSON demons strike again!) Once again, thanks for your generous assistance on this! |
|
Because you have the It's looking for this:
But what it's finding is this:
|
|
To add to @rooster's description. You defined Response like a dictionary, like this:
But if you look closely at the JSON, it's just defined as a loose listing of users, something like this:
The error stated: "Expected to decode Dictionary<String, Any> but found an array instead." So, the decoder had problems trying to map the loose collection of users, to a dictionary. Extended JSON ExampleThis is not part of your solution, but might help clarify the "dictionary" concept. Think about some other JSON that you're examining and want to decode. The JSON might have a collection of users, but it might ALSO have a collection of flowerShops and a collection of taxi cabs. How do you find just the flowerShops in a dictionary? Easy. Like a hardback dictionary, flip to the section named "flowerShops".
|
|
Thank you both for your explanations. I'm getting a little tripped up by dictionaries, as the difference between
and
eludes me. I gather that the the first is somehow a dictionary, but the second is a struct that just contains an array of strings. I thought a dictionary was defined as
which is quite different from the structs I've declared. (Insert sound of head scratching here...) In any case, if I may indulge in one final question about my original problem: I wondered about changing my original defintion of Response to that of an array of User objects, so I change the code to read:
then changed the decoder line to:
The results in a compiler error of:
I'm not sure how to interpret that, as I thought that
would have been equivalent to
as long as Response was a variable of type [User] Thanks once again for your patience in this, as I learn the nuances of JSON decoding. I really do appreciate it! |
|
When you say:
you are creating a property called When you say:
you tell the These two lines:
will only be equivalent if you also have this somewhere in your code:
which sets up |
|
As for your confusion over dictionaries... A dictionary is defined as a key plus a value. So, in Swift, for instance:
defines an empty But remember, you aren't just dealing with Swift here, but also with JSON. In JSON, a dictionary looks like this:
(or whatever type the value is.) When you use this data type in Swift to decode some JSON:
you are telling the decoder that |
|
Think you making getting confused. Paul always says start with the data. If you used Ducky Model Editor and put copy of JSON in this you will get this
You can then add Paul did an extension helper so if you create a file called Decode-URLSession.swift and put this extension in (PS you can also save this to a code snippet for easy use in other projects).
Then in your ContentView (or where ever you doing the call) add
then add this method (again you can also save this to a code snippet for easy use in other projects)
change the "placeholders" and added
then add the
|
SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's all new Paywall Editor allow you to remotely configure your paywall view without any code changes or app updates.
Sponsor Hacking with Swift and reach the world's largest Swift community!
This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.
All interactions here are governed by our code of conduct.
Link copied to your pasteboard.