【问题标题】:Swift JSON Parsing ErrorSwift JSON 解析错误
【发布时间】:2018-02-10 14:37:59
【问题描述】:

我正在尝试解析来自 rest api 的 JSON 响应,但不断出现错误。

我的请求发送和 JSON 解析代码如下,我还添加了 Xcode 的错误消息。

感谢您提前提供的任何帮助。

我的 JSON 格式:

{
    "error":1,
    "name":"batuhan",
    "mail":"mymail@gmail.com",
    "password":"e10adc3949ba59abbe56e057f20f883e",
    "user_type":"user"
}

我的代码:

@IBAction func registerButton(_ sender: Any) {

    let name: String = self.name.text!
    let mail: String = self.mail.text!
    let password: String = self.password.text!


    var responseString: String = ""

    let url = URL(string: "http://my_webserver/index.php?process=register")!
    var request = URLRequest(url: url)
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.httpMethod = "POST"
    let postString = "mail=\(String(describing: mail))&name=\(String(describing: name))&password=\(String(describing: password))&register_type=user"
    request.httpBody = postString.data(using: .utf8)
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {                                                 // check for fundamental networking error
            print("error=\(String(describing: error))")
            return
        }

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(String(describing: response))")
        }

        responseString = String(data: data, encoding: .utf8)!

    }


    struct RegisteredUser: Codable {
        let error: String
        let name: String
        let mail: String
        let password: String
        let user_type: String
    }


    let jsonData = responseString.data(using: .utf8)!
    let decoder = JSONDecoder()
    let user_data = try! decoder.decode(RegisteredUser.self, from: jsonData)

    print(user_data.name)
    print(user_data.mail)


    task.resume()
}

错误:

致命错误:“试试!”表达式意外引发错误: Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No value ." UserInfo={NSDebugDescription=No value.}))): 文件 /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.65/src/swift/stdlib/public/core/ErrorType.swift ,第 181 行

【问题讨论】:

  • 如果你在解码之前登录jsonDataresponseString,你会看到什么?
  • @ItaiFerber 我没有记录它们,即使我把 print(responseString) 放在了 ----responseString = String(data: data, encoding: .utf8) 之后!----它不显示
  • 这意味着,你的代码永远不会被命中,responseString 保持其默认值””,这就是你无法解析它的原因
  • "No value",你的回复是空的?制作有用的打印:在闭包的开头,添加: print("Response: (response)"); print("任务错误:(错误)"); print("Data: (data); (String(data: data, encoding: .utf8)")`; 可能会有所帮助,但我认为您在某处有错误。

标签: ios json swift


【解决方案1】:

您的问题涉及的问题有点过多,显然您应该将其隔离在 JSON 解码中。无论如何:这是(微不足道的)答案。

在您的 JSON 数据中,error 是一个数字,而在您的类定义中,它是一个 String

所以你有两个非常简单的路径来解决你的问题,要么你应该定义

error: Int

在你的RegisteredUser 或者你放

"error":"1",

到你的JSONdata

如果您在开始时显示的内容是从您的 Web 服务返回的,则您必须调整 RegisteredUser 的格式以完全匹配 JSON 数据。请记住:JSONDecoder.decode非常很挑剔,任何好的解析器都应该如此。

如果您正在与网络交谈,我通常建议捕获此类错误并且不要使用try!,因为有太多事情可能出错。虽然我不得不承认,在这种情况下error.localizedDescription 并没有太大帮助

The data couldn’t be read because it isn’t in the correct format.

然而,这确实为我指明了正确的方向,因为它让我更仔细地阅读了您的意见。

更新(带代码)

我在操场上成功解析了你的String,如下:

import Cocoa
struct RegisteredUser: Codable {
    let error: Int
    let name: String
    let mail: String
    let password: String
    let user_type: String
}

var str = """
{
"error":1,
  "name":"batuhan",
  "mail":"mymail@gmail.com",
  "password":"e10adc3949ba59abbe56e057f20f883e",
  "user_type":"user"
}
"""
let jsonData = str.data(using: .utf8)!
let decoder = JSONDecoder()

do {
    let user_data = try decoder.decode(RegisteredUser.self, from: jsonData)
    print(user_data)
} catch {
    print("error on decode: \(error.localizedDescription)")
}

打印出来

RegisteredUser(error: 1, name: "batuhan", mail: "mymail@gmail.com", password: "e10adc3949ba59abbe56e057f20f883e", user_type: "user")

如果您希望我们为您提供帮助,请发布不起作用的代码(以及您期望它执行的操作)。

【讨论】:

  • 不幸的是,将其 String 转换为 Int 不起作用
  • print("error on decode: \(error.localizedDescription)") => print("error on decode: \(error)") 会提供更多信息。
猜你喜欢
  • 1970-01-01
  • 2021-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 2016-02-24
相关资源
最近更新 更多