如何从Yelp Fusion API获取商家分类标题并集成至餐厅应用?
Looks like the crash is happening because your Business struct doesn’t match the structure of Yelp’s API response—let’s break down the issues and fix them step by step.
Key Issues Causing the Crash
- Mismatched Field Name & Type: Yelp returns a
categoriesarray of objects (each withaliasandtitle), but yourBusinessstruct has a singlecategory: Stringfield. The JSON decoder can’t map an array of objects to a string, which triggers the crash. - Snake Case vs. Camel Case Mismatch: Yelp uses snake_case keys like
image_url, but your struct uses camelCase (imageUrl). Without proper decoding setup, this will also cause parsing failures.
Step-by-Step Fixes
1. Create a Category Struct
First, define a struct to represent each individual category object from the API response:
struct Category: Codable { let alias: String let title: String }
2. Update the Business Struct
Replace the incorrect category: String field with a categories array of Category objects. You can either use CodingKeys to map snake_case keys manually, or enable automatic snake case decoding later:
struct Business: Codable { let id: String let name: String let imageUrl: URL let rating: Double let url: String let categories: [Category] // Replaces the old `category` field // Optional: Manual key mapping if you don't want global snake case decoding enum CodingKeys: String, CodingKey { case id, name, rating, url, categories case imageUrl = "image_url" } }
3. Adjust the ViewModel for Category Display
Since categories is an array, you’ll want to format it for user-friendly display (e.g., join all titles into a comma-separated string, or use the first category):
extension RestaurantListViewModel { init(business: Business) { self.name = business.name self.id = business.id self.imageUrl = business.imageUrl self.rating = business.rating self.url = business.url // Join all category titles with commas, or fall back to "Unknown" if empty self.category = business.categories.map { $0.title }.joined(separator: ", ") // Alternative: Use just the first category: business.categories.first?.title ?? "Unknown" } }
4. Configure JSON Decoding (Critical!)
When parsing the API response with Moya, make sure your JSONDecoder is set up to handle snake_case keys (if you didn’t use manual CodingKeys):
// Example when handling Moya response func handleYelpResponse(_ response: Response) { let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase // Auto-maps snake_case to camelCase do { let root = try decoder.decode(Root.self, from: response.data) // Use root.businesses to populate your view model let viewModels = root.businesses.map(RestaurantListViewModel.init) } catch { print("Decoding Error: \(error)") // This will help debug any remaining issues } }
Bonus: Add Error Handling
Always print decoding errors—this gives you clear feedback about what’s going wrong, which is invaluable for debugging future parsing issues.
内容的提问来源于stack exchange,提问作者Mcrich

