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)
}
}
}