在Swift中处理JSON时,如何获取JSON物理字符串的实际「原始」部分?
嘿,我刚好之前也碰到过这个头疼的问题!咱们直接说干货——在Swift里处理JSON时,要拿到它的原始物理字符串,核心得看你当前处于JSON处理的哪个阶段:
- 如果手里还握着原始的Data对象(比如刚从网络请求、本地文件读取回来的未解析数据),那这是最省心的情况,直接把Data转成String就行,拿到的就是100%和数据源一致的原始字符串:
// 假设你已经获取到了原始的jsonData: Data if let rawJsonString = String(data: jsonData, encoding: .utf8) { print(rawJsonString) // 这就是你要的原始物理字符串 }
这种方式完全不会改动原始内容,空格、换行、键的顺序啥的都和最初的JSON一模一样。
如果已经把JSON解析成了Codable对象或者JSONSerialization的字典/数组,那麻烦就来了!因为解析过程中,系统已经把JSON的字符串结构转换成了Swift的对象结构,原始的格式细节(比如多余的空格、换行、键的排列顺序)已经丢失了。这时候如果你想倒回去拿原始字符串,重新序列化出来的结果只是“语义相同”,但格式上和原始物理字符串大概率不一样。
我之前就踩过这个坑——当时先把整个JSON解析成了字典,后来才需要某个子节点的原始字符串,结果用JSONSerialization重新序列化出来的格式和原始的完全不同,折腾了半天才反应过来:最好的办法是在解析之前就把需要的原始Data/String保存好,别等解析完再后悔。如果只需要JSON中某个子节点的原始字符串,而且你已经提前拿到了整个原始Data,那可以先把整个原始字符串切出来(如果知道子节点的大致位置),或者用JSONSerialization解析到某个节点后,再把这个节点重新序列化,但要记住:这种重新序列化的结果是“标准化”后的JSON,和原始物理字符串的格式可能有差异,要是必须要100%一致的原始部分,还是得在解析前就锁定对应的原始Data片段。
举个重新序列化子节点的例子:
// 假设已经解析得到了整个JSON的字典对象jsonObject: [String: Any] if let fruitsArray = jsonObject["fruits"] as? [[String: Any]], let fruitsData = try? JSONSerialization.data(withJSONObject: fruitsArray, options: []) { // 这里的options传空的话会生成紧凑的无格式字符串,传.prettyPrinted会生成带格式的 if let fruitsRawLikeString = String(data: fruitsData, encoding: .utf8) { print(fruitsRawLikeString) } }
再次提醒:这个结果只是语义和原始子节点一致,格式不一定完全相同!
内容来源于stack exchange

