使用Alamofire解码API响应时如何过滤不在枚举范围内的serviceName值
报错原因
你当前的默认Codable逻辑存在两个问题:
Service.Name枚举未包含接口返回的installation、controlunit等serviceName取值- 默认解码数组时只要其中一个元素解码失败,会导致整个数组、甚至整个
ServicesList解码直接失败,无法自动跳过无效条目
最优解决方案(全系统版本兼容)
自定义ServicesList的解码逻辑,先兼容解析所有返回的服务条目,再手动过滤掉不在枚举范围内的无效条目,不需要修改原有模型定义和Alamofire调用逻辑,仅需新增如下代码即可:
extension ServicesList { init(from decoder: Decoder) throws { // 定义临时结构体兼容接口返回的所有字段 struct TempService: Codable { let serviceName: String let date: Date } let container = try decoder.container(keyedBy: CodingKeys.self) // 先将data字段完整解码为临时结构体数组 let tempList = try container.decode([TempService].self, forKey: .services) // 过滤掉serviceName不在枚举范围内的条目,转换为正式Service数组 self.services = tempList.compactMap { temp in guard let validName = Service.Name(rawValue: temp.serviceName) else { return nil } return Service(name: validName, date: temp.date) } } }
可选方案(仅支持iOS 13+/macOS 10.15+)
如果不需要兼容旧系统版本,也可以直接遍历未解码的数组容器,跳过解码失败的条目:
extension ServicesList { init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) var dataContainer = try container.nestedUnkeyedContainer(forKey: .services) var validServices = [Service]() while !dataContainer.isAtEnd { do { let service = try dataContainer.decode(Service.self) validServices.append(service) } catch { // 解码失败直接跳过当前条目 try dataContainer.skip() } } self.services = validServices } }
内容的提问来源于stack exchange,提问作者Giorgio
相关产品推荐
相关产品推荐

