I am trying to pull in and parse a JSON from the Yelp fusion API. Whenever I pull it in and try to parse it and store it as a struct, I get the following error:
Error Domain=NSCocoaErrorDomain Code=4865 "No value associated with key
CodingKeys(stringValue: "businesses", intValue: nil) ("businesses")."
UserInfo={NSCodingPath=(), NSDebugDescription=No value associated with key
CodingKeys(stringValue: "businesses", intValue: nil) ("businesses").}
Here is the struct that I am using:
struct BusinessInfo: Codable {
let total: Int?
let businesses: [Business?]
struct Business: Codable{
let alias: String?
let categories: [Category?]
let coordinates: Coordinates?
let display_phone: String?
let distance: Double?
let id: String?
let image_url: String?
let is_closed: Bool?
let location: Location?
let name: String?
let phone: String?
let price: String?
let rating: Double?
let review_count: Int?
let transactions: [String?]
let url: String?
struct Category: Codable{
let alias: String?
let title: String?
}
struct Coordinates: Codable {
let latitude: Double?
let longitude: Double?
}
struct Location: Codable {
let address1: String?
let address2: String?
let address3: String?
let city: String?
let country: String?
let display_address: [String?]
let state: String?
let zip_code: String?
}
}
struct Region: Codable{
let center: Center?
struct Center: Codable{
let latitude: Double?
let longitude: Double?
}
}
let region: Region?
}
Here is a sample of the JSON data retrieved from the API:
{
businesses = (
{
alias = "the-dixie-cafe-and-quick-stop-keene-2";
categories = (
{
alias = grocery;
title = Grocery;
},
{
alias = irish;
title = Irish;
},
{
alias = "breakfast_brunch";
title = "Breakfast & Brunch";
}
);
coordinates = {
latitude = "37.9434876171571";
longitude = "-84.6388373202724";
};
"display_phone" = "(859) 885-0191";
distance = "6936.03023671068";
id = HG6c8zhWHwn0PF9VdzuQug;
"image_url" = "https://s3-media2.fl.yelpcdn.com/bphoto/R26qmiZSmlIqeQmI17HHvQ/o.jpg";
"is_closed" = 0;
location = {
address1 = "108 Keene-south Elkhorn Rd";
address2 = "";
address3 = "";
city = Keene;
country = US;
"display_address" = (
"108 Keene-south Elkhorn Rd",
"Keene, KY 40339"
);
state = KY;
"zip_code" = 40339;
};
name = "The Dixie Cafe & Quick Stop";
phone = "+18598850191";
price = "$$";
rating = 5;
"review_count" = 11;
transactions = (
);
url = "https://www.yelp.com/biz/the-dixie-cafe-and-quick-stop-keene-2?adjust_creative=aTZyFL2LRvYFp-zGww4qKQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=aTZyFL2LRvYFp-zGww4qKQ";
},
{
alias = "family-tree-cafe-nicholasville";
categories = (
{
alias = tradamerican;
title = "American (Traditional)";
},
{
alias = waffles;
title = Waffles;
},
{
alias = tacos;
title = Tacos;
}
);
coordinates = {
latitude = "37.8671798064261";
longitude = "-84.5775691582197";
};
"display_phone" = "(859) 241-1960";
distance = "3689.465625212305";
id = nf6NYpdzbyeqEwi6RePH4A;
"image_url" = "https://s3-media1.fl.yelpcdn.com/bphoto/wufUljZvejj3wQJwESUiOw/o.jpg";
"is_closed" = 0;
location = {
address1 = "912 S Main St";
address2 = "";
address3 = "<null>";
city = Nicholasville;
country = US;
"display_address" = (
"912 S Main St",
"Nicholasville, KY 40356"
);
state = KY;
"zip_code" = 40356;
};
name = "Family Tree Cafe";
phone = "+18592411960";
rating = 5;
"review_count" = 5;
transactions = (
);
url = "https://www.yelp.com/biz/family-tree-cafe-nicholasville?adjust_creative=aTZyFL2LRvYFp-zGww4qKQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=aTZyFL2LRvYFp-zGww4qKQ";
},
{
alias = "euro-wine-bar-nicholasville";
categories = (
{
alias = tapas;
title = "Tapas Bars";
},
{
alias = "wine_bars";
title = "Wine Bars";
}
);
coordinates = {
latitude = "37.880196";
longitude = "-84.5729947";
};
"display_phone" = "(859) 885-3139";
distance = "3585.476417284776";
id = "4jXOuifkG-qrcII4nnuERQ";
"image_url" = "https://s3-media3.fl.yelpcdn.com/bphoto/9PdiSt2jv5DpbGQzFeVeeQ/o.jpg";
"is_closed" = 0;
location = {
address1 = "102 S Main St";
address2 = "<null>";
address3 = "<null>";
city = Nicholasville;
country = US;
"display_address" = (
"102 S Main St",
"Nicholasville, KY 40356"
);
state = KY;
"zip_code" = 40356;
};
name = "Euro Wine Bar";
phone = "+18598853139";
price = "$$";
rating = 5;
"review_count" = 18;
transactions = (
);
url = "https://www.yelp.com/biz/euro-wine-bar-nicholasville?adjust_creative=aTZyFL2LRvYFp-zGww4qKQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=aTZyFL2LRvYFp-zGww4qKQ";
},
{
alias = "big-city-pizza-nicholasville";
categories = (
{
alias = pizza;
title = Pizza;
},
{
alias = "chicken_wings";
title = "Chicken Wings";
},
{
alias = desserts;
title = Desserts;
}
);
coordinates = {
latitude = "37.8712845368836";
longitude = "-84.57573077733009";
};
"display_phone" = "(859) 885-0111";
distance = "3621.562736763683";
id = "q_qps8wM2iJL5BQvrliDcQ";
"image_url" = "https://s3-media1.fl.yelpcdn.com/bphoto/UWRkMK82sAhX0qf0qYujAQ/o.jpg";
"is_closed" = 0;
location = {
address1 = "114 Williams Rd";
address2 = "<null>";
address3 = "";
city = Nicholasville;
country = US;
"display_address" = (
"114 Williams Rd",
"Nicholasville, KY 40356"
);
state = KY;
"zip_code" = 40356;
};
name = "Big City Pizza";
phone = "+18598850111";
price = "$";
rating = "4.5";
"review_count" = 30;
transactions = (
delivery,
pickup
);
url = "https://www.yelp.com/biz/big-city-pizza-nicholasville?adjust_creative=aTZyFL2LRvYFp-zGww4qKQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=aTZyFL2LRvYFp-zGww4qKQ";
}
);
region = {
center = {
latitude = "37.8844";
longitude = "-84.6135";
};
};
total = 4;
}
And finally, here is the code I am using to call the API and parse the JSON:
let latitude = currentLocation?.latitude
let longitude = currentLocation?.longitude
let apikey = yelpAPIKey
let url = URL(string: "https://api.yelp.com/v3/businesses/search?term=food&latitude=\(String(describing: latitude))&longitude=\(String(describing: longitude))")
var request = URLRequest(url: url!)
request.setValue("Bearer \(apikey)", forHTTPHeaderField: "Authorization")
request.httpMethod = "GET"
//Get JSON from Yelp API
let task = URLSession.shared.dataTask(with: request){ (data, response, error) in
guard let yelpData = data,
error == nil else{
print(error?.localizedDescription ?? "Response Error")
return
}
do{
//Decode the recieved JSON into a BusinessInfo struct
let result = try JSONDecoder().decode(BusinessInfo.self, from: yelpData)
APIBusinessInfo.shared = result
} catch let parsingError as NSError{
//print(yelpData)
print("Error:", parsingError)
}
}
task.resume()
I'm not sure why I am recieving this error so any help would be appreciated.
You need to declare
businesses
array as anOptional
shown below,Also do the same on all the other places where you declared non-optional array of
Optional
e.g,