You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何高效解析含HTML的API响应至PolicyEntity实体?

优化PolicyEntity实体解析方案

问题背景

API返回的是Swift对象的Debug描述字符串(格式如Optional(SBKK.PolicyEntity(errorCode: Optional("222"), message: nil, httpBody: Optional("<html>...</html>")))),当前只能通过字符串索引截取解析,需要更可靠的方式将其转换为PolicyEntity实体,最终提取httpBody内容展示在WebView中。

最优解决方案优先级

  1. 修正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())
        }
    }
    
  2. 自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 08:40:31