iOS请求接口JSON序列化失败,提示格式不正确问题排查
iOS JSON解析错误:"The data couldn’t be read because it isn’t in the correct format." 排查与修复
问题根源与修复步骤
1. 缺失Content-Type请求头
你的POST请求未声明请求体格式,服务器可能无法正确解析参数,返回非JSON内容(比如错误页面),导致解析失败。需添加:
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
2. 强制解包data!存在风险
即使error为nil,data也可能为空或非JSON数据。先判断数据有效性:
guard let data = data else { print("无返回数据") return }
3. 避免使用NSMutableDictionary,改用Swift原生类型
Swift中推荐用[String: Any]替代OC的可变字典,类型更安全:
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { if let id = json["id"] as? String { print(id) } }
4. 手动拼接参数易出错,改用URLComponents编码
手动拼接的参数若包含特殊字符(如空格、@),会导致请求体格式错误,服务器无法处理。用URLComponents自动编码:
let bodyComponents = URLComponents() bodyComponents.queryItems = [ URLQueryItem(name: "username", value: usernameTxt.text?.lowercased() ?? ""), URLQueryItem(name: "password", value: passwordTXT.text ?? ""), URLQueryItem(name: "email", value: emailTxt.text ?? ""), URLQueryItem(name: "fullname", value: "\(nameTxt.text ?? "") \(surnameTxt.text ?? "")") ] request.httpBody = bodyComponents.query?.data(using: .utf8)
完整修复代码
guard let url = URL(string: "http://localhost/DataDog/registering.php") else { return } var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") // 构建编码后的请求体 let bodyComponents = URLComponents() bodyComponents.queryItems = [ URLQueryItem(name: "username", value: usernameTxt.text?.lowercased() ?? ""), URLQueryItem(name: "password", value: passwordTXT.text ?? ""), URLQueryItem(name: "email", value: emailTxt.text ?? ""), URLQueryItem(name: "fullname", value: "\(nameTxt.text ?? "") \(surnameTxt.text ?? "")") ] request.httpBody = bodyComponents.query?.data(using: .utf8) URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print("请求错误:\(error.localizedDescription)") return } guard let data = data else { print("无返回数据") return } // 打印原始返回内容,排查是否为纯JSON if let responseString = String(data: data, encoding: .utf8) { print("服务器返回:\(responseString)") } DispatchQueue.main.async { do { if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { if let id = json["id"] as? String { print("用户ID:\(id)") } // 可扩展处理其他字段 if let status = json["status"] as? String { print("状态码:\(status)") } } } catch let error as NSError { print("JSON解析失败:\(error.localizedDescription)") } } }.resume()
内容的提问来源于stack exchange,提问作者Michael Drammond
相关产品推荐
相关产品推荐

