使用Alamofire解析JSON响应:Postman返回JSON数据的解析问题
如何用Alamofire解析你的JSON响应
嘿,我来告诉你怎么用Alamofire解析这个JSON响应~ 我通常推荐用Swift的Codable协议来做,因为Alamofire对它的支持非常友好,代码也更简洁易维护。当然也可以手动解析JSON字典,我两种方式都给你详细说说。
第一步:定义对应的Codable模型
你的JSON有多层级结构,我们需要逐层定义符合Codable协议的结构体,让Alamofire能自动把JSON映射成Swift对象:
import Foundation // 对应top和popular数组里的单个deal对象 struct Deal: Codable { let id: Int let dealDetail: String // 因为JSON里的key是"deal_detail",Swift推荐驼峰式命名,所以做key映射 enum CodingKeys: String, CodingKey { case id case dealDetail = "deal_detail" } } // 对应result节点的内容 struct ApiResult: Codable { let top: [Deal] let popular: [Deal] // 如果categories有具体结构,这里补充对应的属性即可,比如: // let categories: [Deal] 或者其他自定义模型 } // 对应整个JSON根节点 struct ApiResponse: Codable { let errorcode: String let errorstr: String let result: ApiResult }
第二步:用Alamofire发起请求并自动解析
有了模型之后,就可以用Alamofire的responseDecodable方法直接解析,不用手动处理字典:
import Alamofire // 替换成你的实际API接口地址 let targetUrl = "你的API请求URL" AF.request(targetUrl) .validate() // 自动验证HTTP状态码是否在200-299范围内 .responseDecodable(of: ApiResponse.self) { response in switch response.result { case .success(let apiResponse): // 解析成功,这里可以拿到完整的响应对象 print("请求状态:\(apiResponse.errorstr)") // 处理top数组里的deal数据 let topDeals = apiResponse.result.top for deal in topDeals { print("Top Deal ID: \(deal.id)") // 注意dealDetail是HTML转义后的字符串,需要解码才能得到正常HTML let decodedHtml = deal.dealDetail .replacingOccurrences(of: "<", with: "<") .replacingOccurrences(of: ">", with: ">") .replacingOccurrences(of: """, with: "\"") print("解码后的Deal详情:\(decodedHtml)") } // 处理popular数组的逻辑和top一样 let popularDeals = apiResponse.result.popular // ... 这里写你的业务逻辑 case .failure(let error): // 请求或解析失败,处理错误 print("请求出错:\(error.localizedDescription)") } }
备选方案:手动解析JSON字典
如果你暂时不想用Codable,也可以用responseJSON手动解析字典结构:
AF.request(targetUrl) .validate() .responseJSON { response in switch response.result { case .success(let jsonValue): // 先把JSON转成字典 guard let rootDict = jsonValue as? [String: Any] else { print("JSON格式不是预期的字典类型") return } // 解析根节点的错误信息 let errorcode = rootDict["errorcode"] as? String ?? "未知" let errorstr = rootDict["errorstr"] as? String ?? "未知" print("错误码:\(errorcode),提示:\(errorstr)") // 解析result节点 guard let resultDict = rootDict["result"] as? [String: Any] else { print("result字段格式错误") return } // 解析top数组 if let topDealsArray = resultDict["top"] as? [[String: Any]] { for dealDict in topDealsArray { let dealId = dealDict["id"] as? Int ?? 0 let dealDetail = dealDict["deal_detail"] as? String ?? "" print("Top Deal ID: \(dealId),详情:\(dealDetail)") // 同样可以处理HTML转义 } } // 解析popular数组同理 if let popularDealsArray = resultDict["popular"] as? [[String: Any]] { // ... 你的处理逻辑 } case .failure(let error): print("请求失败:\(error.localizedDescription)") } }
额外注意点
- HTML转义处理:你的
deal_detail字段是HTML实体转义后的字符串(比如<对应<),如果要在UI上显示成富文本,可以用AttributedString的init(html:)方法来解析,或者像上面代码那样手动替换常用的实体。 - 模型扩展性:如果
categories字段有具体的JSON结构,只需要在ApiResult结构体里补充对应的属性,并确保它遵循Codable协议即可。 - 类型匹配:要保证模型里的属性类型和JSON里的类型完全匹配,比如
errorcode在JSON里是字符串("0"),所以模型里要用String类型,不能用Int。
内容的提问来源于stack exchange,提问作者user8977455
相关产品推荐
相关产品推荐

