使用Codable协议解析多层嵌套数组时遇解码错误
Fixing the "Expected to decode Array but found a dictionary instead" Codable Error for Your Nested API Response
Let's break down what's happening here: that error means somewhere in your Codable model definitions, you've declared a property as an array type (like [SomeType]), but the API is returning a single dictionary (object) at that position. Looking at your sample response, the entire top-level structure is a dictionary (not an array), and the only array lives under Students.Enrollments.
Step 1: Define Correct Codable Models
You need to create structs that mirror the exact hierarchy of your API response. Here's how to model it properly:
// Top-level response model that holds both FatherModel and Students struct ParentStudentResponse: Codable { let fatherModel: FatherModel let students: Students // Map snake_case API keys to camelCase Swift properties enum CodingKeys: String, CodingKey { case fatherModel = "FatherModel" case students = "Students" } } struct FatherModel: Codable { let userId: Int let parentType: String let partnerId: Int let educationId: Int let user: User enum CodingKeys: String, CodingKey { case userId = "UserId" case parentType = "ParentType" case partnerId = "PartnerId" case educationId = "EducationId" case user = "User" } } struct User: Codable { let id: Int let firstName: String let lastName: String enum CodingKeys: String, CodingKey { case id = "Id" case firstName = "FirstName" case lastName = "LastName" } } struct Students: Codable { let id: Int let enrollments: [Enrollment] enum CodingKeys: String, CodingKey { case id = "Id" case enrollments = "Enrollments" } } struct Enrollment: Codable { let id: Int let studentId: Int let classId: Int enum CodingKeys: String, CodingKey { case id = "Id" case studentId = "StudentId" case classId = "ClassId" } }
Step 2: Decode the Response
Once your models are set up correctly, you can decode the data like this:
// Assume you have your API response data stored in the 'data' variable do { let decoder = JSONDecoder() let response = try decoder.decode(ParentStudentResponse.self, from: data) // Access your decoded data here print("Father's full name: \(response.fatherModel.user.firstName) \(response.fatherModel.user.lastName)") if let firstEnrollment = response.students.enrollments.first { print("First enrollment ID: \(firstEnrollment.id)") } } catch { print("Decoding failed: \(error.localizedDescription)") // For more detailed debugging, print the full error print("Full error details: \(error)") }
Common Mistakes to Avoid
- Top-level array mismatch: The biggest culprit is usually trying to decode
[FatherModel].selfor[Students].selfdirectly—your API returns a single dictionary containing both models, not an array of either. - Nested type mismatches: Double-check that properties like
fatherModel(a single object) aren't declared as[FatherModel], and thatenrollments(the only array in the response) is correctly typed as[Enrollment]. - CodingKeys typos: Ensure your
CodingKeysexactly match the case-sensitive key names in the API response (e.g., "FatherModel" vs "fathermodel" will break decoding).
内容的提问来源于stack exchange,提问作者Android teem
相关产品推荐
相关产品推荐

