Swift中如何用单个Model适配两种不同格式的API响应?
解决API返回格式不统一的解析问题
核心问题是API返回格式不一致:不传withID时返回包含userInfo数组的对象,传入withID时返回单个ResultItem对象。要统一解析成[ResultItem],推荐两种解决方式:
方法一:自定义Model的解码逻辑(推荐)
通过给Results结构体实现自定义Codable解码逻辑,让它自动适配两种返回格式,同时修正ResultItem的编码忽略问题:
修改后的Model代码
struct ResultItem: Codable, Identifiable { let id = UUID() let userId: String var userlastname: String var username: String // 忽略API不返回的id字段 enum CodingKeys: String, CodingKey { case userId, userlastname, username } } struct Results: Codable { let userInfo: [ResultItem] // 自定义解码逻辑,适配两种返回格式 init(from decoder: Decoder) throws { do { // 先尝试解析无ID请求的格式:带userInfo数组的对象 let keyedContainer = try decoder.container(keyedBy: CodingKeys.self) userInfo = try keyedContainer.decode([ResultItem].self, forKey: .userInfo) } catch { // 解析失败则尝试解析单个ResultItem,包装成数组 let singleItem = try ResultItem(from: decoder) userInfo = [singleItem] } } enum CodingKeys: String, CodingKey { case userInfo } // 可选:实现编码逻辑以满足Codable协议完整要求 func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(userInfo, forKey: .userInfo) } }
修改后,原请求函数getUsers里的解码代码完全不用改动,就能自动处理两种返回情况,最终都能得到[ResultItem]数组。
方法二:在网络回调中手动判断处理
如果不想修改Model,可以在拿到返回数据后手动判断JSON类型,再分别解析:
修改后的请求回调代码
URLSession.shared.dataTask(with: urlHeader) { [self] (data, response , error) in guard let data = data else { completion(.failure(.missingData)) // 需补充对应NetworkError枚举case return } print(String(data: data, encoding: .utf8) ?? "Invalid JSON") do { let json = try JSONSerialization.jsonObject(with: data, options: []) if let _ = json as? [String: Any], let singleItem = try? JSONDecoder().decode(ResultItem.self, from: data) { // 处理单个ResultItem的情况 completion(.success([singleItem])) } else if let results = try? JSONDecoder().decode(Results.self, from: data) { // 处理带userInfo数组的情况 completion(.success(results.userInfo)) } else { throw NetworkError.invalidResponse } } catch { print("Error:\(error)") completion(.failure(error as? NetworkError ?? .unknown)) } }.resume()
这种方式无需改动Model,但代码可读性和扩展性不如第一种方法。
内容的提问来源于stack exchange,提问作者coder hard
相关产品推荐
相关产品推荐

