Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

iOS

Deysha Rivera
Deysha Rivera
5,088 Points

Playground Run Disabled for Wrapper Keys - Lists of Objects

I can manually run the Playground and everything compiles, but If I just try to use the "Play" button, it is greyed out. I have tried opening new playgrounds and copying and pasting the code with the same results. Everything worked fine up until adding the "Candidates" code from this video. If I try to delete the new code, the playground still doesn't work properly.

import Foundation

let json = """
{
    "work": {
        "id": 2422333,
        "books_count": 222,
        "ratings_count": 860687,
        "text_reviews_count": 37786,
        "best_book": {
            "id": 375802,
            "title": "Ender's Game (Ender's Saga, #1)",
            "author": {
                "id": 589,
                "name": "Orson Scott Card"
            }
        },
        "candidates": [
            {
                "id": 44687,
                "title": "Enchanters' End Game (The Belgariad, #5)",
                "author": {
                    "id": 8732,
                    "name": "David Eddings"
                }
            },
            {
                "id": 22874150,
                "title": "The End Game",
                "author": {
                    "id": 6876994,
                    "name": "Kate  McCarthy"
                }
            },
            {
                "id": 7734468,
                "title": "Ender's Game: War of Gifts",
                "author": {
                    "id": 236462,
                    "name": "Jake Black"
                }
            }
        ]
    }
}
""".data(using: .utf8)!

struct SearchResult {
    let id: Int
    let booksCount: Int
    let ratingsCount: Int
    let textReviewsCount: Int
    let bestBook: Book
    let candidates: [Book]

    enum OuterCodingKeys: String, CodingKey {
        case work
    }

}

struct Author: Codable {
    let id: Int
    let name: String
}

struct Book: Codable {
    let id: Int
    let title: String
    let author: Author
}

enum CodingKeys: String, CodingKey {
    case id
    case booksCount
    case ratingsCount
    case textReviewsCount
    case bestBook
    case candidates
}

extension SearchResult: Decodable {
    init(from decoder: Decoder) throws {
        let outerContainer = try decoder.container(keyedBy: OuterCodingKeys.self)
        let innerContainer = try outerContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .work)

        self.id = try innerContainer.decode(Int.self, forKey: .id)
        self.booksCount = try innerContainer.decode(Int.self, forKey: .booksCount)
        self.ratingsCount = try innerContainer.decode(Int.self, forKey: .ratingsCount)
        self.textReviewsCount = try innerContainer.decode(Int.self, forKey: .textReviewsCount)
        self.bestBook = try innerContainer.decode(Book.self, forKey: .bestBook)
        self.candidates = try innerContainer.decode([Book].self, forKey: .candidates)
    }
}

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

let result = try! decoder.decode(SearchResult.self, from: json)
result.bestBook.title
result.bestBook.author.name
result.candidates.count

extension SearchResult: Encodable {
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: OuterCodingKeys.self)
        var innerContainer = container.nestedContainer(keyedBy: CodingKeys.self, forKey: .work)

        try innerContainer.encode(id, forKey: .id)
        try innerContainer.encode(booksCount, forKey: .booksCount)
        try innerContainer.encode(ratingsCount, forKey: .ratingsCount)
        try innerContainer.encode(textReviewsCount, forKey: .textReviewsCount)
        try innerContainer.encode(bestBook, forKey: .bestBook)
        try innerContainer.encode(candidates, forKey: .candidates)
    }
}

let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase


print(try! encoder.encode(result).stringDescription)


let candidatesJson = """
{
"candidates": [
{
"id": 44687,
"title": "Enchanters' End Game (The Belgariad, #5)",
"author": {
"id": 8732,
"name": "David Eddings"
}
},
{
"id": 22874150,
"title": "The End Game",
"author": {
"id": 6876994,
"name": "Kate  McCarthy"
}
},
{
"id": 7734468,
"title": "Ender's Game: War of Gifts",
"author": {
"id": 236462,
"name": "Jake Black"
}
}
]
}
""".data(using: .utf8)!

let candidates = try! decoder.decode([String: [Book]].self, from: candidatesJson)