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

iOS12下JSONEncoder编码String失败但iOS13+正常,是什么原因?

问题根因

你遇到的是iOS 12系统Foundation框架中JSONEncoder的已知限制:

  • iOS 12及更低版本中,JSONEncoder不支持直接编码顶层的基础类型(包括String、Int、Bool、Float等),只有把这些值放到数组、字典等容器类型中才能正常完成编码
  • 该限制在iOS 13及更高版本中被官方修复,所以你在高版本系统中运行没有问题
修复方案

可以通过两种方式兼容iOS 12系统:

方案1:单独处理String类型

String类型可以直接转UTF8数据,不需要走JSON编码,调整后的代码如下:

class StoreManager {
     public static func save<T: Codable>(_ value: T, forKey key: String) {
        let data: Data?
        if let strValue = value as? String {
            data = strValue.data(using: .utf8)
        } else {
            data = try? JSONEncoder().encode(value)
        }
        guard let finalData = data else { 
           return 
        }
        try? keychain.set(finalData, key: key)
     }
}

读取的时候也对应处理String类型即可。

方案2:通用包装层适配

如果希望所有类型统一走JSON编码逻辑,可以加一个通用的Codable包装器:

struct CodableWrapper<T: Codable>: Codable {
    let value: T
}

// 保存时包装后再编码
let data = try? JSONEncoder().encode(CodableWrapper(value: value))
// 读取时先解码包装器,再取出实际值
let wrapper = try? JSONDecoder().decode(CodableWrapper<T>.self, from: data)
let value = wrapper?.value

内容的提问来源于stack exchange,提问作者limbo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:48:00