使用Codable解析嵌套JSON遇阻:数组对象解析及Encodable协议报错求助
Hey there! Let's work through this Codable issue together—sounds like you’ve got the hang of fetching the id field already, but hitting a wall when dealing with nested arrays (like those coordinates) and getting that frustrating "Type 'Feature' does not conform to protocol 'Encodable'" error. Let’s break this down step by step to get you back on track.
First: Match Your Model to the JSON Structure
The #1 reason for Codable conformity errors is a mismatch between your Swift model and the actual JSON structure. Let’s use a common geospatial JSON example (since you’re dealing with coordinates) to illustrate:
Example JSON Structure
{ "features": [ { "id": "geo-123", "geometry": { "coordinates": [-122.4194, 37.7749] } } ] }
Corresponding Swift Models
You need to define nested structs that mirror every level of the JSON. Every property in these structs must conform to Codable (which most basic types like String, Double, and arrays of them do automatically):
// First, the nested geometry object that holds coordinates struct Geometry: Codable { let coordinates: [Double] // Matches the array of lat/long values } // Now your Feature struct—notice it includes the Geometry type, which is Codable struct Feature: Codable { let id: String let geometry: Geometry // Add any other fields from your JSON here (e.g., "type", "properties") } // A top-level struct to wrap the array of features struct GeoResponse: Codable { let features: [Feature] }
Why You’re Seeing the "Encodable" Error
That error pops up when one or more properties in your Feature struct don’t conform to Encodable. Common culprits:
- You forgot to make a nested struct (like
Geometry) conform toCodable. - You have a custom type in
Featurethat hasn’t been marked asCodable(and doesn’t have manual encoding/decoding logic). - If you only need to parse JSON (not encode it), you can switch to conforming only to
Decodableinstead ofCodable—this simplifies things if encoding isn’t a requirement.
Extracting Latitude & Longitude
Once your models are set up correctly, parsing and extracting coordinates is straightforward:
// Assume you have your JSON data (from a network request or local file) let jsonData: Data = // Your data source here do { let response = try JSONDecoder().decode(GeoResponse.self, from: jsonData) // Loop through features to pull out coordinates for feature in response.features { // Note: Geospatial JSON usually uses [longitude, latitude] order let longitude = feature.geometry.coordinates[0] let latitude = feature.geometry.coordinates[1] print("Found location: Lat \(latitude), Long \(longitude)") } } catch { // Print detailed errors to debug mismatches print("Parsing failed: \(error.localizedDescription)") print("Full error details: \(error)") // This will tell you exactly which field is mismatched }
Debugging Tips
- Check key casing: If your JSON uses camelCase (e.g., "geometry") but your Swift model uses PascalCase (e.g., "Geometry"), use
CodingKeysto map them:struct Feature: Codable { let id: String let geometry: Geometry enum CodingKeys: String, CodingKey { case id case geometry = "Geometry" // Matches JSON's uppercase key } } - Handle optional fields: If some fields in the JSON are optional, mark them with
?in your model (e.g.,let geometry: Geometry?). - Print full error messages: The generic "conformity" error is vague, but the full
errorobject will tell you exactly which property or key is causing the issue.
You’ve already made progress by getting the id field working—you’re just one step away from cracking the nested array parsing. Stick with it, and match those models closely to your JSON structure!
内容的提问来源于stack exchange,提问作者Jacob Jidell

