Swift 4 Decodable: 给定的数据不是有效的 JSON

14

我正在尝试向我的本地服务器编写POST请求,这是我的函数:

@IBAction func postButtonAction(_ sender: UIButton) {

    guard let url = URL(string:"http://localhost:443/api/message") else {return}
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    print("POSTED")

    let date : Date = Date()
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
    let dateTime = dateFormatter.string(from: date)

    let newPost = MessageForPost(message: "Hi", timestamp: dateTime, latitude: "1.1", longitude: "2.2")
    let newData = DataForPost(message: newPost)
    let newPackage = PackageForPost(data: newData)

    do {
        let jsonBody = try JSONEncoder().encode(newPackage)
        request.httpBody = jsonBody
        print("jsonBody:",jsonBody)
        let jsonBodyString = String(data: jsonBody, encoding: .utf8)
        print("JSON String : ", jsonBodyString!)
    } catch let err  {
        print("jsonBody Error: ",err)
    }

    let session = URLSession.shared
    let task = session.dataTask(with: request){ (data,response,err) in

        guard let data = data else {return}

        do{
            let sendPost = try JSONDecoder().decode(PackageForPost.self, from: data)
            print("DATA:\(data)")
        }catch let err{

            print("Session Error: ",err)
        }
    }
    task.resume()
}

这里使用的是以下结构体:

struct PackageForPost:Encodable, Decodable{
    let data: DataForPost
}

struct DataForPost:Encodable, Decodable{
    let message: MessageForPost
}

struct MessageForPost:Codable {
    let message: String
    let timestamp: String
    let latitude: String
    let longitude: String
}

它能够打印

JSON String :  {"data":{"message":{"message":"Hi","timestamp":"2017-10-18 00:50:13","latitude":"1.1","longitude":"2.2"}}}

会话错误:dataCorrupted(Swift.DecodingError.Context(codingPath: [],debugDescription:“给定的数据无效JSON。”, underlyingError:Optional(Error Domain = NSCocoaErrorDomain Code = 3840 “JSON文本未以数组或对象开头,并且没有设置选项允许 片段。”UserInfo = {NSDebugDescription = JSON文本没有 开始与数组或对象和选项不允许片段。}))

为什么它不是有效的JSON???

这是我的服务器API POST请求文件:

POST
/api/message

{
    data: {
        message: {

            message: “Hey, a new message!”,
            timestamp: 2017-09-10 10:22:33,
            latitude: 62.233589156441724,
            longitude: 25.735066461654696
        }
   } 
}

我已经进行了相当多的谷歌搜索,但在这里卡了很长时间!任何帮助都感激不尽!


我在 Playground 中运行了你的基本解码代码,它运行良好。我建议你将 Data 解码为 String 并打印出来,以确保你知道自己要解码的内容,因为如果以 POST 开头,那就是你的问题所在。 - MadProgrammer
1
decode行之前打印接收到的数据:print(data as NSData)。第一个字节必须是7B。错误信息显示它不是。 - vadian
3
@vadian所说的没错。你提出的问题似乎暗示了你认为构建数据的方式有问题,但实际上并没有。你收到的错误信息实际上是将JSON字符串解码为Swift对象时产生的错误。当它说文本必须以数组或对象开头时,意思是该字符串必须以[{其中之一开头。可能服务器返回的不是JSON格式的响应。 - JeremyP
它不是以POST开头,所以我猜那不是问题...但无论如何还是谢谢你!还有感谢你编辑我的问题格式!@MadProgrammer - Kei
错误信息与以 Session Error 开头的字符串相关,因此它是服务器响应。 - vadian
显示剩余5条评论
1个回答

4

很简单...我遇到了同样的问题。

你的结构体将时间戳、纬度和经度解码和编码为字符串,而JSON的类型是Double或Floating类型。

struct MessageForPost:Codable {
    let message: String
    let timestamp: String
    let latitude: String
    let longitude: String
}

这里涉及到JSON格式

{
    data: {
        message: {
            message: "Hey, a new message!",
            timestamp: 2017-09-10 10:22:33,
            latitude: 62.233589156441724,
            longitude: 25.735066461654696
        }
   } 
}

我在我的端口修复了它,然后...它奏效了...

编辑 使用相同的数据类型...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接