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

Swift JSON解析函数未返回Failure却崩溃,原因是什么?

问题:解析JSON函数遇无效输入崩溃,未返回错误结果

我编写了一个解析输入JSON的函数,设计目标是解析失败时返回友好错误,但遇到无效JSON时,应用直接在以下代码行崩溃:

let data = try? JSONSerialization.data(withJSONObject: result),

完整函数代码如下:

static func parseModel<Response: Decodable>(from response: Any?, with error: Error? = nil) -> Result<Response, Error> {
            guard let result = response,
                let data = try? JSONSerialization.data(withJSONObject: result),
                  let model = try? JSONDecoder().decode(Response.self, from: data)
            else { return .failure(error ?? APIError.emptyResponse) }

            return .success(model)
        }

为何该函数未返回.failure(error ?? APIError.emptyResponse),反而直接崩溃?


原因及解决方案

崩溃原因

JSONSerialization.data(withJSONObject:) 方法的特殊行为导致了崩溃:当传入的对象不是JSON合法类型时,它不会抛出可被try?捕获的Error,而是直接触发运行时崩溃。try?仅能处理函数抛出的异常,无法拦截运行时崩溃,因此代码执行到这一行时直接终止,根本没机会进入guard的else分支返回错误结果。

常见的非法输入场景包括:传入NSNull、存在循环引用的对象、包含JSON不支持的类型(如未处理的Date实例、未遵循JSONSerialization要求的自定义类)等。

修复方案

核心思路是提前校验输入对象是否符合JSON序列化要求,避免触发崩溃:

static func parseModel<Response: Decodable>(from response: Any?, with error: Error? = nil) -> Result<Response, Error> {
    guard let result = response else {
        return .failure(error ?? APIError.emptyResponse)
    }
    
    // 先校验对象是否可被JSON序列化
    guard JSONSerialization.isValidJSONObject(result),
          let data = try? JSONSerialization.data(withJSONObject: result),
          let model = try? JSONDecoder().decode(Response.self, from: data) else {
        // 建议新增APIError.invalidResponse类型,替代emptyResponse更精准
        return .failure(error ?? APIError.invalidResponse)
    }
    
    return .success(model)
}

额外优化建议:拆分guard条件,分别处理不同阶段的错误(如对象非法、序列化失败、解码失败),返回对应错误类型,便于后续排查问题。


内容的提问来源于stack exchange,提问作者Evgeniy Kleban

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 03:04:56