Swift中如何高效解析含HTML的API响应至PolicyEntity实体?
优化PolicyEntity实体解析方案
问题背景
API返回的是Swift对象的Debug描述字符串(格式如Optional(SBKK.PolicyEntity(errorCode: Optional("222"), message: nil, httpBody: Optional("<html>...</html>")))),当前只能通过字符串索引截取解析,需要更可靠的方式将其转换为PolicyEntity实体,最终提取httpBody内容展示在WebView中。
最优解决方案优先级
修正API返回格式(推荐)
直接要求后端返回标准JSON格式,示例如下:{"errorCode":"222","message":null,"httpBody":"<html><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">...</html>"}这种情况下,
PolicyEntity的Decodable协议可直接生效,无需额外处理:AF.request(request).responseDecodable(of: PolicyEntity.self) { response in switch response.result { case .success(let model): successHandler(model as! T) case .failure(let error): print("解析失败: \(error)") failHandler(ErrorCode()) } }自定义Debug字符串解析(API无法修改时)
利用正则表达式提取字段值,给PolicyEntity添加自定义初始化方法适配Debug字符串格式:extension PolicyEntity { init?(fromDebugString string: String) { // 提取errorCode let errorCodePattern = #"errorCode: Optional\((\"?)(.*?)\1\)"# let errorCodeMatch = string.range(of: errorCodePattern, options: .regularExpression) errorCode = errorCodeMatch.flatMap { let capture = string[$0].replacingOccurrences(of: errorCodePattern, with: "$2", options: .regularExpression) return capture.isEmpty ? nil : capture } // 提取message let messagePattern = #"message: (nil|Optional\((\"?)(.*?)\2\))"# let messageMatch = string.range(of: messagePattern, options: .regularExpression) if let matchRange = messageMatch { let messagePart = string[matchRange].replacingOccurrences(of: messagePattern, with: "$1", options: .regularExpression) if messagePart == "nil" { message = nil } else { let content = messagePart.replacingOccurrences(of: #"Optional\((\"?)(.*?)\1\)"#, with: "$2", options: .regularExpression) message = content.isEmpty ? nil : content } } else { message = nil } // 提取httpBody并还原转义字符 let httpBodyPattern = #"httpBody: Optional\((\"?)([\s\S]*?)\1\)"# let httpBodyMatch = string.range(of: httpBodyPattern, options: .regularExpression) httpBody = httpBodyMatch.flatMap { var content = string[$0].replacingOccurrences(of: httpBodyPattern, with: "$2", options: .regularExpression) // 还原转义的双引号 content = content.replacingOccurrences(of: "\\\"", with: "\"") return content.isEmpty ? nil : content } } }在请求方法中替换原解析逻辑:
case .success: guard let responseString = response.value, let model = PolicyEntity(fromDebugString: responseString) else { print("AF.request failure") failHandler(ErrorCode()) return } successHandler(model as! T)
注意事项
- 正则解析依赖Debug字符串的格式稳定性,若后端修改结构体的Debug输出(如字段顺序、命名),解析逻辑需同步调整。
- 优先选择API返回标准JSON,这是最可靠、可维护的方案。
内容的提问来源于stack exchange,提问作者Marcel Kopera
相关产品推荐
相关产品推荐

