JSONSerialization:是什么、Foundation类方法及工作原理

作者: IT Sectr 发布日期: 2026-03-15 阅读时间: 8 分钟

JSONSerialization — 是Foundation框架中内置的iOS类,用于将JSON转换为Foundation对象及其反向转换。该API是Apple平台上无需连接第三方库即可处理JSON的基本机制,支持字典、数组和原始类型的解析。根据Apple Developer, 2024JSONSerialization支持使用Data、流和读取选项灵活处理JSON数据。

要点

  • JSONSerialization — 用于在iOS和macOS上解析JSON的内置Foundation类
  • jsonObject — 将JSON Data转换为Foundation字典和数组的方法
  • data — 将Foundation对象序列化回JSON Data的方法
  • isValidJSONObject — 检查对象是否可以序列化为JSON
  • Codable — 具有类型化序列化的现代Swift替代方案

什么是JSONSerialization

JSONSerialization — 是Foundation框架中的一个类,可在iOS、macOS、tvOS和watchOS上使用。它提供了将JSON Data转换为Foundation对象(NSDictionary、NSArray、NSString、NSNumber)及其反向转换的方法。该类出现在iOS 5中,并在Codable(Swift 4)引入之前一直是Apple平台上处理JSON的主要方式。尽管年代久远,JSONSerialization在Objective-C遗留项目中以及在没有固定模型模式需要动态处理JSON的场景中仍然被广泛使用。

何时使用JSONSerialization

尽管Codable已经出现,JSONSerialization在多种场景中仍然具有相关性。动态JSON结构 — 当响应格式变化或事先未知时 — 需要通过键访问字典,这通过JSONSerialization更容易实现。该类还用于Codable不可用的Objective-C项目中,以及使用流逐步解析大型JSON文件时。在测试和模拟中,isValidJSONObject和data(withJSONObject:options:)允许无需连接第三方库即可快速生成JSON固定数据,从而加速开发和原型设计。

swift
import Foundation

// 使用JSONSerialization的基本结构
let jsonString = """
{
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com"
}
"""

guard let jsonData = jsonString.data(using: .utf8) else {
    return
}

do {
    let json = try JSONSerialization
        .jsonObject(with: jsonData,
                       options: .mutableContainers)
    print(json)
} catch {
    print("JSON解析错误:\(error)")
}

类的主要方法

JSONSerialization提供了四种主要的JSON处理方法。主要方法 — jsonObject(with:options:),它将Data转换为Foundation对象。data(withJSONObject:options:)方法执行反向序列化。isValidJSONObject(_:)检查对象是否可以被序列化。writeJSONObject(_:to:options:error:)直接将JSON写入流。要从InputStream读取JSON,存在jsonObject(with:options:)方法,它接受流而不是Data,这在集成返回流数据的网络请求时很方便。

JSONObject和JSONData

jsonObject方法接受Data并返回Any — 通常是NSDictionary或NSArray。为了安全操作,结果通过条件转换转换为预期的类型。data方法接受Foundation对象并返回带有JSON表示的Data。.prettyPrinted选项添加带缩进的格式化以提高可读性。

swift
let jsonString = """
{
    "products": [
        {"id": 1, "name": "iPhone", "price": 999},
        {"id": 2, "name": "iPad", "price": 799}
    ]
}
"""
let data = Data(jsonString.utf8)

if let json = try? JSONSerialization
    .jsonObject(with: data) as? [String: Any],
    let products = json["products"] as? [[String: Any]] {

    for product in products {
        if let name = product["name"] as? String {
            print("产品:\(name)")
        }
    }
}

// 反向序列化:对象 -> JSON
let outputDict: [String: Any] = ["status": "ok", "count": 42]
if let outputData = try? JSONSerialization
    .data(withJSONObject: outputDict,
                options: .prettyPrinted) {
    String(data: outputData, encoding: .utf8)
}

JSON解析示例

基本解析带有原始类型的字典 — 最常见的JSONSerialization操作。通过URLSession接收Data后,开发人员调用jsonObject并将结果转换为期望的类型。对于对象数组,使用转换为[[String: Any]],然后在循环中处理每个元素。这种方法很灵活,但需要手动类型管理。

解析嵌套结构

真实的API会返回带有数组、日期和可选字段的复杂嵌套JSON对象。JSONSerialization正确处理任何嵌套深度,但开发人员必须独立地将每个级别转换为所需的类型。为简化此任务,Apple建议对类型化数据使用Codable,而仅对动态结构使用JSONSerialization。

swift
// 解析API响应
func parseUserResponse(data: Data) {
    do {
        guard let json = try JSONSerialization
            .jsonObject(with: data) as? [String: Any]
        else { return }

        guard let userId = json["id"] as? Int,
              let name = json["name"] as? String
        else {
            throw ParsingError.missingField
        }

        print("用户:\(name) (ID:\(userId))")

    } catch let error as ParsingError {
        print("解析失败:\(error)")
    } catch {
        print("意外错误:\(error)")
    }
}

enum ParsingError: Error {
    case missingField
    case invalidType
}

错误处理

JSONSerialization在JSON无效、类型不匹配或嵌套深度超限时抛出错误。错误属于CocoaError类型,并包含带有问题描述的代码。开发人员必须通过do-catch构造处理它们,否则应用程序将意外终止。最常见的错误:NSPropertyListReadCorruptError(错误的JSON)和NSPropertyListReadUnknownError。每种错误类型都需要自己的处理策略:在格式无效时需要请求重新发送数据,在结构不匹配时需要更新解析模型。

反序列化时的错误类型

无效的JSON — 最常见的失败原因:缺少逗号、多余字符或未转义的引号会破坏整个解析。第二种错误类型 — 与预期结构不匹配:例如,服务器返回了数组而不是字典。JSONSerialization.fragmentsAllowed允许读取根不是字典或数组而是原始值的JSON。当JSON包含过多层次结构时,开发人员还可能遇到嵌套深度超限错误。

读写选项

JSONSerialization提供了多种配置解析的选项。.mutableContainers返回NSMutableDictionary和NSMutableArray而不是不可变版本,这在解析后修改数据时很有用。.mutableLeaves使文本值可修改。.fragmentsAllowed允许根不是对象或数组而是字符串或数字的JSON — 这对于简单的API响应很方便。.withoutEscapingSlashes和.sortedKeys选项可用于data(withJSONObject:options:)方法,控制序列化JSON的格式。选项通过位掩码传递,允许通过|运算符组合多个值以实现灵活的解析配置。

swift
// 处理不同类型的错误
func safeParse(jsonData: Data) {
    do {
        let object = try JSONSerialization
            .jsonObject(with: jsonData,
                           options: .fragmentsAllowed)

        if let dictionary = object as? [String: Any] {
            print("包含\(dictionary.count)个键的字典")
        } else if let array = object as? [Any] {
            print("包含\(array.count)个项目的数组")
        }

    } catch CocoaError.propertyListReadCorrupt {
        print("损坏的JSON数据")
    } catch let error as CocoaError {
        print("Cocoa错误:\(error)")
    } catch {
        print("未知错误:\(error)")
    }
}

// 序列化前检查对象有效性
let testObject: [String: Any] = ["key": "value", "nested": ["a": 1]]
if JSONSerialization.isValidJSONObject(testObject) {
    print("有效的JSON对象")
}

JSONSerialization的性能受数据大小和调用频率的影响。在一次性解析小型服务器响应时,差异不明显,但在处理数十兆字节JSON或循环中频繁调用时,需要考虑类型转换的开销。JSONSerialization同步工作在当前线程中,因此对于大型文档,建议通过DispatchQueue.global()将解析移至后台队列。或者,可以使用InputStream进行流式处理而无需将整个文件加载到内存中,这对于资源受限的应用程序至关重要。要将JSON写入文件或网络流,writeJSONObject(_:to:options:error:)方法允许将序列化数据直接路由到OutputStream而无需创建中间Data对象,从而减少处理大型文档时的内存消耗。

常见问题

iOS中的JSONSerialization是什么?

JSONSerialization — 是一个Foundation类,用于将JSON Data转换为Foundation对象(NSDictionary、NSArray)及其反向转换。它在iOS、macOS、tvOS和watchOS上运行,无需连接额外的库。

JSONSerialization和Codable有什么区别?

Codable — 是一个Swift协议,用于自动类型化序列化,它编译为类型安全代码。JSONSerialization使用动态的Any类型,需要手动转换。Codable更适用于新项目,JSONSerialization适用于Objective-C和动态数据。

如何解析JSON时处理错误?

在调用jsonObject时使用do-catch构造。JSONSerialization错误属于CocoaError。调试时检查NSPropertyListReadCorruptError,它指示JSON数据格式无效。

JSONSerialization支持嵌套结构吗?

是的,JSONSerialization支持任意深度的字典和数组嵌套。所有嵌套对象都会转换为相应的Foundation类型(NSDictionary、NSArray、NSString、NSNumber),同时保留原始JSON结构。

何时使用JSONSerialization而不是Codable?

JSONSerialization适用于动态JSON结构、Objective-C项目、使用流处理以及通过isValidJSONObject验证JSON。对于具有已知模式的类型化结构,Codable更受欢迎。

总结

  • JSONSerialization — Apple平台上用于基本JSON处理的内置Foundation类
  • jsonObject — 主要的解析方法,将Data转换为Foundation字典和数组
  • data — Foundation对象反向序列化为JSON Data的方法,带格式化选项
  • isValidJSONObject — 检查对象是否可序列化为JSON的谓词
  • 错误处理必须通过do-catch进行,以防止应用程序意外终止
  • Codable — 具有已知数据模式的Swift项目的现代类型化替代方案

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读