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

Posted

技术标签:

【中文标题】Swift 4 Decodable:给定的数据不是有效的 JSON【英文标题】:Swift 4 Decodable: The given data was not valid JSON 【发布时间】:2018-03-30 01:03:56 【问题描述】:

我正在尝试向本地服务器写入 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。", 基础错误:可选(错误域=NSCocoaErrorDomain 代码=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 开头,那么这就是您的问题 打印接收到的数据:print(data as NSData)decode 行之前。第一个字节必须是7B。错误消息说,它不是。 @vadian 说了什么。您已经提出了这个问题,就好像您认为构建数据的方式有问题一样。没有。您得到的错误消息实际上是从 decoding 一个 JSON 字符串到 Swift 对象。当它说文本必须以数组或对象开头时,这意味着字符串必须分别以[ 开头。可能来自服务器的响应不是 JSON 它不是以 POST 开头的,所以我想这不是问题......但还是谢谢你!以及其他感谢您编辑我的问题格式! @MadProgrammer 它以<3c21444f 开头,也以> 结尾,这些算不算括号? @vadian 【参考方案1】:

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

看看你的结构是解码和编码时间戳、纬度和经度,因为字符串和 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
        
    

....我在最后修复了它并且...它起作用了..

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

【讨论】:

以上是关于Swift 4 Decodable:给定的数据不是有效的 JSON的主要内容,如果未能解决你的问题,请参考以下文章

处理包含多种类型的 JSON 数组 - Swift 4 Decodable

Swift 5:给定的数据不是有效的JSON(将数据从API加载到表格视图)

Swift 4 JSON Decodable 解码类型更改的最简单方法

Swift 4 Decodable - 没有与键 CodingKeys 关联的值 [重复]

在 Swift 4 中使用 Decodable 解析 JSON

使用 Swift 4 的 Decodable 解码 Void