Swift4 Codable解码空数组问题求助
解决Swift Codable解码空数组失败的问题
你遇到的问题其实不是空数组导致的解码失败,而是JSON中部分字段的类型和Swift结构体定义不匹配,引发了解码错误,让你误以为是空数组的锅。下面具体分析并给出解决方案:
问题根源
看你的JSON数据,customer_id是数字类型(比如825),但你在Details结构体里把它定义成了String?类型。直接用try values.decode(String.self, forKey: .customer_id)解码时,类型不匹配会抛出错误,导致整个Details初始化失败,最终details变成nil,你才会误以为是address空数组的问题。
而空数组[]其实是Codable原生支持的,不需要特殊处理——它会被正常解码为空的[Address]数组(如果是可选类型就是Some([]))。
解决方案
方案一:修正字段类型匹配(推荐)
直接把结构体中类型不匹配的字段改成和JSON一致的类型,比如把customer_id改成Int?,这样可以完全依赖Codable的默认实现,不需要自定义解码方法:
import Foundation struct Signup: Codable { var success: String? var message: String? var details: Details? // 无需自定义CodingKeys和init(from:),默认就能处理所有字段 } struct Details: Codable { var address: [Address]? var cart_count: String? var customer_id: Int? // 改为Int类型,匹配JSON的数字类型 var customer_status: String? var email: String? var firstname: String? var full_name: String? var is_customer_verified: String? var is_delivery_available: String? var is_registration_complete: String? var lastname: String? var mobile: String? var name_type: String? var pincode: String? var profile_pic: String? var referral_code: String? // 无需自定义CodingKeys和init(from:) } struct Address: Codable { var address_default: String? var address_id: String? var address_type: String? var city: String? var customer_id: String? var flat_or_house_or_office_no: String? var full_address: String? var full_name: String? var landmark: String? var lat: String? var lng: String? var mobile: String? var name_type: String? var pincode: String? var street_or_society_or_office_name: String? }
方案二:保留String类型,自定义处理类型转换
如果业务要求customer_id必须是String?类型,那需要在自定义解码方法中处理Int转String的逻辑,同时空数组直接正常解码即可:
struct Details: Codable { var address: [Address]? var cart_count: String? var customer_id: String? var customer_status: String? var email: String? var firstname: String? var full_name: String? var is_customer_verified: String? var is_delivery_available: String? var is_registration_complete: String? var lastname: String? var mobile: String? var name_type: String? var pincode: String? var profile_pic: String? var referral_code: String? private enum CodingKeys: String, CodingKey { case address, cart_count, customer_id, customer_status, email, firstname, full_name, is_customer_verified, is_delivery_available, is_registration_complete, lastname, mobile, name_type, pincode, profile_pic, referral_code } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) // 空数组直接正常解码,无需try? address = try values.decode([Address].self, forKey: .address) cart_count = try values.decode(String.self, forKey: .cart_count) // 处理customer_id的类型转换:先尝试解码Int,再转成String;如果本身是String就直接解码 if let customerIdInt = try? values.decode(Int.self, forKey: .customer_id) { customer_id = String(customerIdInt) } else { customer_id = try values.decode(String.self, forKey: .customer_id) } // 其他字段正常解码 customer_status = try values.decode(String.self, forKey: .customer_status) email = try values.decode(String.self, forKey: .email) firstname = try values.decode(String.self, forKey: .firstname) full_name = try values.decode(String.self, forKey: .full_name) is_customer_verified = try values.decode(String.self, forKey: .is_customer_verified) is_delivery_available = try values.decode(String.self, forKey: .is_delivery_available) is_registration_complete = try values.decode(String.self, forKey: .is_registration_complete) lastname = try values.decode(String.self, forKey: .lastname) mobile = try values.decode(String.self, forKey: .mobile) name_type = try values.decode(String.self, forKey: .name_type) pincode = try values.decode(String.self, forKey: .pincode) profile_pic = try values.decode(String.self, forKey: .profile_pic) referral_code = try values.decode(String.self, forKey: .referral_code) } }
总结
- Codable原生支持空数组解码,不需要额外处理;
- 解码失败的核心原因是JSON字段类型与Swift结构体字段不匹配,优先修正类型或自定义处理类型转换;
- 尽量避免不必要的自定义解码方法,减少出错概率。
内容的提问来源于stack exchange,提问作者Alok
相关产品推荐
相关产品推荐

