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

Swift中使用ObjectMapper解析JSON时的空数组解析异常问题

解决ObjectMapper解析含空数组的JSON返回nil的问题

看起来你遇到的是JSON字段类型与模型属性类型不匹配导致的解析失败问题——服务器在无数据时把本该返回对象的字段(比如myKpiMonth/myKpiWeek)返回成了空数组[],而ObjectMapper无法自动将空数组映射到对象类型的属性,最终导致整个模型初始化失败返回nil。

下面给你两种实用的解决方案:

方案一:自定义类型转换器(复用性强)

先写一个通用转换器,把空数组转换成nil,这样ObjectMapper遇到空数组时会自动把对应属性设为nil,而不是解析失败:

class EmptyArrayToNilTransform<T: Mappable>: TransformType {
    typealias Object = T?
    typealias JSON = Any
    
    func transformFromJSON(_ value: Any?) -> T? {
        guard let value = value else { return nil }
        // 检测到空数组,直接返回nil
        if let emptyArray = value as? [Any], emptyArray.isEmpty {
            return nil
        }
        // 正常情况映射为目标对象
        return Mapper<T>().map(JSONObject: value)
    }
    
    func transformToJSON(_ value: T?) -> Any? {
        return value?.toJSON()
    }
}

然后在你的模型类里,给有问题的属性绑定这个转换器:

class GetTodayMyKpiResponse: Mappable{
    var status: String?
    var myKpiMonth: MyKpiMonthResponse?
    var myKpiWeek: MyKpiWeekResponse?
    
    required init?(map: Map){ }
    
    func mapping(map: Map) {
        status <- map["status"]
        // 给myKpiMonth和myKpiWeek绑定转换器
        myKpiMonth <- (map["myKpiMonth"], EmptyArrayToNilTransform<MyKpiMonthResponse>())
        myKpiWeek <- (map["myKpiWeek"], EmptyArrayToNilTransform<MyKpiWeekResponse>())
    }
}

方案二:在mapping方法里手动处理(快速解决)

如果不想写通用转换器,也可以直接在mapping方法里判断字段类型,手动处理空数组的情况:

class GetTodayMyKpiResponse: Mappable{
    var status: String?
    var myKpiMonth: MyKpiMonthResponse?
    var myKpiWeek: MyKpiWeekResponse?
    
    required init?(map: Map){ }
    
    func mapping(map: Map) {
        status <- map["status"]
        
        // 处理myKpiMonth字段
        if let rawValue = map["myKpiMonth"].currentValue {
            if let emptyArray = rawValue as? [Any], emptyArray.isEmpty {
                myKpiMonth = nil
            } else {
                myKpiMonth <- map["myKpiMonth"]
            }
        } else {
            myKpiMonth <- map["myKpiMonth"]
        }
        
        // 同理处理myKpiWeek字段
        if let rawValue = map["myKpiWeek"].currentValue {
            if let emptyArray = rawValue as? [Any], emptyArray.isEmpty {
                myKpiWeek = nil
            } else {
                myKpiWeek <- map["myKpiWeek"]
            }
        } else {
            myKpiWeek <- map["myKpiWeek"]
        }
    }
}

这两种方法都能解决你的问题:当服务器返回空数组时,模型对应的属性会被设为nil,而不是整个模型解析失败返回nil。如果是MyKpiMonthResponse或MyKpiWeekResponse内部的数组字段遇到空数组,只要你把这些数组属性定义为可选类型(比如var kpiItems: [KpiItem]?)或者非可选空数组(var kpiItems: [KpiItem] = []),ObjectMapper都能正常解析,不需要额外处理。

内容的提问来源于stack exchange,提问作者Rahul Gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:56:58