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
相关产品推荐
相关产品推荐

