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

Swift解码JSON时如何自动解密SHA-256加密的URL字段?

解决方案:自定义Codable解码逻辑自动解密URL

当然可以实现!核心思路是重写TableCellData的自定义解码初始化器,在解码url字段的环节直接调用你的SHA-256解密函数,把加密后的字符串解密后再转换成URL类型。这样整个解码流程完成后,url属性就已经是可用的正常URL,完全不需要在后续使用时再额外处理。

步骤1:先定义你的解密函数

假设你已经有一个处理SHA-256解密的函数,示例如下(你需要替换成自己的实际解密逻辑):

func decryptSHA256(_ encryptedString: String) -> String? {
    // 这里编写你的SHA-256解密逻辑,返回解密后的原始URL字符串
    // 举个模拟例子:假设加密前缀是"sha256_",解密时移除该前缀
    return encryptedString.replacingOccurrences(of: "sha256_", with: "")
}

步骤2:重写TableCellData的解码初始化器

修改你的TableCellData结构体,添加自定义的init(from decoder: Decoder)方法,在解码url字段时插入解密逻辑:

struct TableCellData: Codable {
    let type: Int
    let cellText: String
    let cellImage: String?
    let url: URL?
    let detailText: String?
    let tableID: Int?
    
    enum CodingKeys: String, CodingKey {
        case type = "type"
        case cellText = "cell_text"
        case cellImage = "cell_image"
        case url = "url"
        case detailText = "detail_text"
        case tableID = "table_id"
    }
    
    // 自定义解码初始化器,替换默认的自动解码逻辑
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        // 先解码不需要特殊处理的字段
        type = try container.decode(Int.self, forKey: .type)
        cellText = try container.decode(String.self, forKey: .cellText)
        cellImage = try container.decodeIfPresent(String.self, forKey: .cellImage)
        detailText = try container.decodeIfPresent(String.self, forKey: .detailText)
        tableID = try container.decodeIfPresent(Int.self, forKey: .tableID)
        
        // 处理url字段:解码加密字符串 → 解密 → 转换为URL
        if let encryptedUrlString = try container.decodeIfPresent(String.self, forKey: .url) {
            if let decryptedUrlString = decryptSHA256(encryptedUrlString) {
                url = URL(string: decryptedUrlString)
            } else {
                // 解密失败时,将url设为nil(也可根据需求抛出解码错误)
                url = nil
            }
        } else {
            // 接口返回url字段为null时,直接设为nil
            url = nil
        }
    }
}

// 保留你原有的扩展代码无需修改
extension TableCellData {
    init?(data: Data) {
        guard let me = try? JSONDecoder().decode(TableCellData.self, from: data) else { return nil }
        self = me
    }
    
    init?(_ json: String, using encoding: String.Encoding = .utf8) {
        guard let data = json.data(using: encoding) else { return nil }
        self.init(data: data)
    }
    
    init?(fromURL url: String) {
        guard let url = URL(string: url) else { return nil }
        guard let data = try? Data(contentsOf: url) else { return nil }
        self.init(data: data)
    }
    
    var jsonData: Data? {
        return try? JSONEncoder().encode(self)
    }
    
    var json: String? {
        guard let data = self.jsonData else { return nil }
        return String(data: data, encoding: .utf8)
    }
}

为什么这样可行?

当你调用JSONDecoder().decode(TableCellData.self, from: data)时,解码器会自动使用我们自定义的init(from decoder: Decoder)方法,而非默认的自动解码逻辑。这样我们就能在解码url字段的流程中,无缝插入解密步骤,确保最终的url属性是解密后的可用URL。

额外说明

  • 如果解密失败或者解密后的字符串无法转换成URL,上面的代码会把url设为nil,你也可以根据业务需求改成抛出解码错误(比如throw DecodingError.dataCorrupted(...))。
  • 你原有的扩展代码不需要做任何修改,因为init?(data: Data)依然依赖JSONDecoder,而解码器现在会自动使用我们的自定义解码逻辑。

内容的提问来源于stack exchange,提问作者Mr Some Dev.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:56:04