You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:36:20