使用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
相关产品推荐
相关产品推荐

