Swift 4 Decodable: The given data was not valid JSON

21,488

It was simple .. i had the same kind of issue..

Look your Struct is Decoding and Encoding Timestamp, latitude and longitude as as Strings and JSON is in Double or Floating type.

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

And here Json

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

.... I fixed it at my end and... it worked..

Edited use the same data type..

Share:
21,488
Kei
Author by

Kei

Junior developer in iOS.

Updated on January 06, 2020

Comments

  • Kei
    Kei over 4 years

    I'm trying to write a POST request to my local server, this is my function:

    @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()
    }
    

    These are the structs using here:

    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
    }
    

    And it was able to print

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

    But it keeps showing this ERROR:

    Session Error: dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.})))

    Why is it not a valid JSON???

    Here's my server's API POST request document:

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

    I've done quite some googling but am stuck here for a very long time! Any help appreciated!