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

使用Swift 4 Decodable解析JSON/纯文本服务响应遇问题求助

处理iOS后端JSON/纯文本混合响应的解决方案

这个问题我之前开发项目时也碰到过,后端这种“成功返回JSON、失败返回纯文本”的设计确实有点反常规,但我们可以通过先尝试JSON解码,失败后再解析纯文本错误的思路来完美解决。

问题根源

你遇到的NSCocoaErrorDomain Code=3840错误,本质是因为JSONDecoder只能解析标准JSON格式(必须以{}或[]开头),而后端返回的纯文本不符合这个要求,所以解码直接失败。

具体实现方案

假设你用URLSession发起网络请求,可以按以下步骤处理响应:

首先,保持你已有的Response结构体不变:

struct Response: Decodable {
    let message: String
}

然后在网络请求的回调中,先尝试解码JSON,失败后再处理纯文本:

func fetchBackendData(completion: @escaping (Result<Response, String>) -> Void) {
    guard let requestUrl = URL(string: "你的后端接口地址") else {
        completion(.failure("无效的请求地址"))
        return
    }
    
    let task = URLSession.shared.dataTask(with: requestUrl) { data, _, error in
        // 先处理网络层面的基础错误
        if let networkError = error {
            completion(.failure(networkError.localizedDescription))
            return
        }
        
        guard let responseData = data else {
            completion(.failure("后端未返回任何数据"))
            return
        }
        
        // 第一步:尝试解码成功的JSON响应
        let decoder = JSONDecoder()
        do {
            let successResponse = try decoder.decode(Response.self, from: responseData)
            completion(.success(successResponse))
        } catch {
            // 第二步:捕获JSON解码失败的情况,尝试解析纯文本错误
            if let errorText = String(data: responseData, encoding: .utf8) {
                completion(.failure(errorText))
            } else {
                // 极端情况:既不是JSON也不是可解析的纯文本,返回原始错误
                completion(.failure(error.localizedDescription))
            }
        }
    }
    task.resume()
}

进阶优化:精准判断错误类型

如果你想更精准地只处理“非JSON格式”导致的解码失败(而不是JSON格式正确但字段不匹配的情况),可以专门捕获3840错误码:

do {
    let successResponse = try decoder.decode(Response.self, from: responseData)
    completion(.success(successResponse))
} catch let decodingError as NSError 
        where decodingError.domain == NSCocoaErrorDomain && decodingError.code == 3840 {
    // 确认是JSON格式错误,解析纯文本错误信息
    if let errorText = String(data: responseData, encoding: .utf8) {
        completion(.failure(errorText))
    } else {
        completion(.failure("无法解析错误信息"))
    }
} catch {
    // 处理其他解码错误(比如JSON字段不匹配)
    completion(.failure("数据解析失败:\(error.localizedDescription)"))
}

这样就能完美适配后端的两种响应模式:成功时拿到解析好的业务数据,失败时直接获取后端返回的纯文本错误提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:07:31