JSON Custom CodingKeys
AppStore JSON APIs
For the many different JSON sources that you'll come across during app development, the chances that you'll want to customize the decoding process is quite high. To facilitate this, Swift provides something called CodingKeys that allows you to specify which fields get parsed into which properties. I'll walk you through how to do this for the ratings in our iTunes JSON api.

Comments (12)
ayon
4 years ago
Hi Brian, tx for this amazing course. I was wondering if you have any plans to introduce any cell separator style in the collectionView as we have in the appStore app. Like using a decorativeView
ZiadHamdieh
4 years ago
I think he said he would leave the implementation of the separator line up to us. I would also like to see him do it just to know if he has a really practical/easy way of doing it.
ZiadHamdieh
4 years ago
Hey Brian any chance you can provide the asset for the stars?
Brian Voong
4 years ago
tsangaris
4 years ago
Hey Brian, For pushing the body content closer to the stars and leave the empty space (if any) at the bottom, I introduced a UIView() inside the stackview() right after the bodyLabel. It looks to be working just fine. Is it ok?
Brandon Jacobi
4 years ago
This is exactly what I did and it worked, seems like a really good solution.
Brian Voong
4 years ago
need2edit
4 years ago
Really great course. FYI since the app store can reset reviews when a new version is updated, the 'entry' property needs to be optional since no review entries might be returned.
mitul
4 years ago
Instead of using an image view for showing the rating, I plan to use the star emoji. Eg. let starsLabel: UILabel = UILabel(text: "⭐️", font: .systemFont(ofSize: 16))
Stewart Lynch
4 years ago
If there are no reviews, then you can handle the decoding with an optional value for the entries array. However, if you only have a single review, then entry does not come as an array of objects, but rather as a single dictionary like this following. How do you handle this in decoding? "entry": { "author": { "uri": { "label": "https://itunes.apple.com/de/reviews/id35449630?l=en" }, "name": { "label": "lemonpilot" }, "label": "" }, "im:version": { "label": "1.2" }, "im:rating": { "label": "5" }, "id": { "label": "1355731245" }, "title": { "label": "A great app ..." },
Stewart Lynch
4 years ago
In case anyone else is interested, I have solved the problem where the entry object can be nil, a single entry or [entry]. If you redefine your ReviewFeed struct like this, it handles all cases. Credit goes, as usual, to StackOverflow. I just had to dig far enough and piece together a couple of responses. struct ReviewFeed: Decodable { var entry: [Entry] = [] init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) do { entry = try container.decode([Entry].self, forKey: .entry) } catch { switch error { case DecodingError.typeMismatch(let expectedType, _) where expectedType == [Any].self || expectedType == [Entry].self: let singleEntry = try container.decode(Entry.self, forKey: .entry) entry = [singleEntry] case DecodingError.keyNotFound(_, _): entry = [] default: print("error decoding data:", error) } } } enum CodingKeys: String, CodingKey { case entry } }
dclawson
3 years ago
Here's the homework for the over-achievers: how would you implement this for an API that had half star ratings? Not really interested in the solution because the API doesn't have non-int ratings, but it's fun to think about how you'd do it for one that did.
dclawson
3 years ago
Also, the best part about this stage of the course: reading the reviews of "Tinder". #dumpsterfire
Kritbovorn Taweeyossak
3 years ago
How to fit reviews content : Height ReviewCell ; for each review cell, please ?
Brian Voong
3 years ago
Kritbovorn Taweeyossak
3 years ago
Thanks you , Sir Ohm ,,, Can you suggest solution for doing that , please
Lazaro Ambrosio
2 years ago
It gives me this error when clicking on a cell to find out the star's rating label from the review?.feed.entry.forEach({print($0.rating.label)}) Failed to decode keyNotFound(CodingKeys(stringValue: "rating", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "feed", intValue: nil), CodingKeys(stringValue: "entry", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"rating\", intValue: nil) (\"rating\").", underlyingError: nil))
Lazaro Ambrosio
2 years ago
Haha nevermind my issue is that I wrote CodingKeys with a lowercase k rather than an uppercase K. *Shrugs*
HELP & SUPPORT