json - `JSONDecoder` 如何知道使用哪种编码?
问题描述
像一个好孩子一样阅读了Joel 关于 EncodingJSONDecoder
的文章后,我发现自己对 Foundation 的工作方式感到困惑,其init
或decode
方法都没有编码值。浏览文档,我看到了实例变量dataDecodingStrategy,这也许就是编码猜测魔法发生的地方......?
我在这里错过了什么吗?不需要JSONDecoder
知道它接收到的数据的编码吗?我意识到 JSON 标准要求这些数据采用 UTF-8 编码,但可以JSONDecoder
做出这样的假设吗?我很困惑。
解决方案
RFC 8259(从 2017 年开始)要求
在不属于封闭生态系统的系统之间交换的 JSON 文本必须使用 UTF-8 编码。
较旧的RFC 7159(从 2013 年开始)和RFC 7158(从 2013 年开始)仅声明
JSON 文本应以 UTF-8、UTF-16 或 UTF-32 编码。默认编码是 UTF-8,并且以 UTF-8 编码的 JSON 文本是可互操作的,因为它们将被最大数量的实现成功读取;有许多实现无法成功读取其他编码(例如 UTF-16 和 UTF-32)的文本。
和RFC 4627(从 2006 年开始,我能找到的最古老的):
JSON 文本应以 Unicode 编码。默认编码为 UTF-8。
由于 JSON 文本的前两个字符始终是 ASCII 字符,因此可以通过查看来确定八位字节流是 UTF-8、UTF-16(BE 或 LE)还是 UTF-32(BE 或 LE)前四个八位字节中的空值模式。
JSONDecoder
(JSONSerialization
在引擎盖下使用)能够解码 UTF-8、UTF-16 和 UTF-32,包括 little-endian 和 big-endian。例子:
let data = "[1, 2, 3]".data(using: .utf16LittleEndian)!
print(data as NSData) // <5b003100 2c002000 32002c00 20003300 5d00>
let a = try! JSONDecoder().decode([Int].self, from: data)
print(a) // [1, 2, 3]
由于有效的 JSON 文本必须以“[”或“{”开头,因此可以从数据的第一个字节明确地确定编码。
不过,我没有发现此文档,并且可能不应该依赖它。未来的实现JSONDecoder
可能仅支持较新的标准并需要 UTF-8。
推荐阅读
- laravel - 在单个路由中使用名称属性设置 Throttle 属性
- laravel - 页面未找到 404 Laravel
- arrays - 如何使用辅助函数来填充用户输入大小的数组?
- javascript - 如何将单击事件处理程序添加到从 javascript 创建的 userChat 类
- timer - 如何在 PIC16F1827 上同步两个定时器
- kotlin-multiplatform - 为什么我不能在 Windows 上使用 KMM 插件运行 iOS 项目?
- dart - 在函数调用中使用 int 作为 num
- java - 在 React Native Android 应用程序中通过 crashlytics 的堆栈跟踪找到崩溃是真的吗?
- python - 请求发布后获取上传的文件名 - python
- usb - STM32f103 HAL USB - UART桥接器