iOS中Alamofire结合Codable处理嵌套JSON数据失败求助
解决Alamofire + Codable解析嵌套JSON数组的问题
嘿,作为iOS开发新手,刚接触Alamofire和Codable确实会有点懵,我帮你梳理下问题所在,然后给出完整的修正方案:
首先,你的代码里存在几个关键问题:
- JSON结构与Codable类型不匹配:
原JSON中subscriptions是数组([]包裹),但你定义的User结构体里把它声明成了单个subscriptions对象;course_extensions同样是数组,但你定义成了单个course_extensions对象 - 数据类型不匹配:
JSON里的batch_user_id、id、course_id都是数字类型,但你在结构体里声明成了String,解码时会直接失败 - Alamofire请求没有用Codable直接解码:
你用了responseJSON配合SwiftyJSON,其实Alamofire自带responseDecodable可以直接将响应解码为你的Codable模型,流程更简洁
修正后的完整代码:
1. 修正Codable结构体(遵循Swift类型命名规范:首字母大写)
// 嵌套的课程扩展模型,完全匹配JSON数据类型 struct CourseExtension: Codable { let id: Int let amount: String let courseId: Int let isActive: Bool let numberOfDays: Int // 用CodingKeys映射JSON蛇形命名到Swift驼峰命名(更符合Swift编码规范) private enum CodingKeys: String, CodingKey { case id, amount case courseId = "course_id" case isActive = "is_active" case numberOfDays = "number_of_days" } } // 订阅项模型,修正数组类型与数据类型 struct Subscription: Codable { let batchUserId: Int let batchName: String let courseName: String let startDate: String let endDate: String let noOfDays: Int let totalNoOfDays: Int let extendedDate: String let extended: Bool let courseExtensions: [CourseExtension] // 改为数组类型,对应JSON的[]结构 private enum CodingKeys: String, CodingKey { case batchUserId = "batch_user_id" case batchName = "batch_name" case courseName = "course_name" case startDate = "start_date" case endDate = "end_date" case noOfDays = "no_of_days" case totalNoOfDays = "total_no_of_days" case extendedDate = "extended_date" case extended, courseExtensions } } // 顶层响应模型,修正subscriptions为数组类型 struct UserResponse: Codable { // 改名更贴合实际响应内容 let subscriptions: [Subscription] // 注意:你的原JSON里没有status和message字段,必须去掉这两个属性,否则解码会失败! }
2. 修正Alamofire请求代码,用responseDecodable直接解码
// MARK: - Service call func fetchUserData() { AF.request(SMAConstants.my_subscriptions, method: .get) .responseDecodable(of: UserResponse.self) { response in switch response.result { case .success(let userResponse): // 成功解码后直接访问嵌套数据 let subscriptions = userResponse.subscriptions for subscription in subscriptions { print("批次名称:\(subscription.batchName)") // 遍历嵌套的courseExtensions数组 for extensionItem in subscription.courseExtensions { print("扩展ID:\(extensionItem.id),额外天数:\(extensionItem.numberOfDays)") } } case .failure(let error): print("解码失败:\(error.localizedDescription)") // 可选:打印原始响应数据排查问题 if let rawData = response.data { print("原始响应数据:\(String(data: rawData, encoding: .utf8) ?? "无法解析")") } } } }
关键说明:
- Swift命名规范:结构体名和属性名用首字母大写的驼峰命名,通过
CodingKeys映射JSON的蛇形命名,代码可读性更高 - 数组类型匹配:JSON里用
[]包裹的内容,必须对应Swift的数组类型(比如[Subscription]、[CourseExtension]) - 数据类型严格对应:JSON中的数字对应Swift的
Int,字符串对应String,布尔值对应Bool,类型不匹配会导致解码失败 - Alamofire原生解码:
responseDecodable是Alamofire专为Codable设计的方法,无需额外依赖第三方库,解码流程更高效
这样修改后,你就能顺利解析嵌套数组的数据了!
内容的提问来源于stack exchange,提问作者Code92
相关产品推荐
相关产品推荐

