How do I properly call this async function to return data?

Viewed 17

I'm working through Develop in Swift, in the process of decoding JSON into a custom model object. When using the function to unwrap the data I get the error "Expected '(' in argument list of function declaration" & Expected 'func' keyword in instance method declaration. I don't see any reason the code shouldn't compile. Is this a bug?

  struct StoreItem: Codable {
    var name: String
    var artist: String
    var kind: String
    var description: String
    var artworkURL: URL
    
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        name = try values.decode(String.self, forKey: CodingKeys.name)
        artist = try values.decode(String.self, forKey: CodingKeys.artist)
        kind = try values.decode(String.self, forKey: CodingKeys.kind)
        artworkURL = try values.decode(URL.self, forKey: CodingKeys.artworkURL)
        
        if let description = try? values.decode(String.self, forKey: CodingKeys.description) {
            self.description = description
        } else {
            let additionalValues = try decoder.container(keyedBy: AdditionalKeys.self)
            description = (try? additionalValues.decode(String.self, forKey: AdditionalKeys.longdescription)) ?? ""
        }
        
    }
    
    enum CodingKeys: String, CodingKey {
        case name = "trackName"
        case artist = "artistName"
        case kind
        case description
        case artworkURL = "artworkUrl"
    }
    
    enum AdditionalKeys: CodingKey {
        case longdescription
    }
    
}

struct SearchResponse: Codable {
    let results: [StoreItem]
    
    enum StoreItemError: Error, LocalizedError {
        case itemNotFound
    }
    
    func fetchItems(matching query: [String: String]) async throws -> [StoreItem] {
        var urlComponents = URLComponents(string:  "https://itunes.apple.com/search")!
        urlComponents.queryItems = query.map {
            URLQueryItem(name: $0.key, value: $0.value)
        }
        let (data, response) = try await URLSession.shared.data(from: urlComponents.url!)
        guard let httpResponse = response as? HTTPURLResponse,
              httpResponse.statusCode == 200 else {
            throw StoreItemError.itemNotFound
        }
        let decoder = JSONDecoder()
        let searchResponse = try decoder.decode(SearchResponse.self, from: data)
        
        return searchResponse.results
        
    }
    
    var query = [
        "term": "Apple",
        "media": "ebook",
        "attribute": "authorTerm",
        "lang": "en_us",
        "limit": "10"
    ]
    
    Task {
        do {
            let storeItems = fetchItems(matching: query)
            storeItems.forEach { item in
                print("""
Name: \(item.name)
""")
            }
        }
        catch {
            print(error)
        }
    }

}
0 Answers
Related