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

Xcode 13.1与iOS 15.0环境下JSON序列化崩溃:Invalid top-level type in JSON write问题排查求助

问题根源分析

你遇到的崩溃核心原因是:JSONSerialization只能序列化Foundation框架的原生类型(比如NSDictionary、NSArray、String、Number等),而你传入的是自定义的RoomBookings结构体实例,它不属于JSONSerialization能处理的顶级类型,所以抛出了Invalid top-level type的错误。

虽然你的结构体遵循了Codable协议,但JSONSerialization和Codable是两套独立的序列化系统,不能混用。

解决方案

你有两个可行的解决方向,推荐用方案一(因为你已经实现了Codable相关的扩展):

方案一:使用你已经实现的Codable扩展来序列化

你的RoomBookings结构体已经有了jsonData()方法,直接用它替代JSONSerialization即可,这是最简洁的方式:

var jsonData: Data
do {
    // 直接调用结构体自带的jsonData()方法
    jsonData = try roomBookings.jsonData()
} catch {
    print("error: ", error)
    return false
}

方案二:手动将自定义类型转换为Foundation原生类型(不推荐,冗余)

如果你一定要用JSONSerialization,需要先把RoomBookings转成字典类型,不过这需要手动编写转换逻辑,不如Codable方便:

// 先把RoomBookings转成字典
let bookingDict: [String: Any] = [
    "bookings": roomBookings.bookings.map { booking in
        [
            "bookingId": booking.bookingID,
            "roomId": booking.roomID,
            "isAllDay": booking.isAllDay,
            "startTimestamp": booking.startTimestamp,
            "endTimestamp": booking.endTimestamp,
            "user": booking.user
        ] as [String: Any]
    }
]

var jsonData: Data
do {
    jsonData = try JSONSerialization.data(withJSONObject: bookingDict, options: [])
} catch {
    print("error: ", error)
    return false
}
额外说明

你提到的isValidJSONObject检查确实能避免崩溃,它的作用就是验证传入的对象是否是JSONSerialization支持的类型——显然你的RoomBookings实例会返回false,这也印证了我们的分析。

另外,你的Codable扩展已经写得很完整了,直接用它序列化/反序列化是最符合Swift现代开发习惯的方式,完全没必要再用JSONSerialization这套旧API。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 02:02:32