'URLRequest Error "The given data was not valid JSON."

Trying to make a POST request with headers and params

Codeable code:

struct WelcomeMessage: Codable {
   let receivedMessages: [ReceivedMessage]
}

// MARK: - ReceivedMessage
struct ReceivedMessage: Codable, Identifiable  {
    let ackID: String
    let message: Message
    let id = UUID()

    enum CodingKeys: String, CodingKey {
        case ackID
        case message
    }
}

// MARK: - Message
struct Message: Codable {
    let data, messageID, publishTime: String

    enum CodingKeys: String, CodingKey {
        case data
        case messageID
        case publishTime
    }
}

Service code:

class GetMessages: ObservableObject {
    private var project_id: String = "redacted"
    private var project_name: String = "redacted"
    
    @Published var messages = [ReceivedMessage]()

    func getMessages() {
        guard let url = URL(string: "https://pubsub.googleapis.com/v1/projects\(project_id)/subscriptions\(project_name):pull") else {return}
        
        var request = URLRequest(url: url)
        let parameters : [String:Any] = [
            "returnImmediately": false,
            "maxMessages": 10]
        
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("Bearer ya29.redacted", forHTTPHeaderField: "Authorization")
        
        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
        } catch let error {
            print(error.localizedDescription)
            return
        }
        
        URLSession.shared.dataTask(with: request) { (data, response, error) in
            guard error == nil else {print(error!.localizedDescription); return }
            // guard let data = data else {print("empty data"); return }

            let theData = try! JSONDecoder().decode(WelcomeMessage.self, from: data!)
            print(theData)
            DispatchQueue.main.async {
                self.messages = theData.receivedMessages
            }
            
        }
        .resume()
    }
}

The response to the request should return some JSON data that looks like:

{
  "receivedMessages": [
    {
      "ackId": "UdfdsfdsfdsfdsfdgfhgfjJHGkjkjhKgjhgjFhgfDFgfdgDFGDFdfgFDGfd",
      "message": {
        "data": "//BASE-64 ENCODED STRING HERE",
        "messageId": "4130086024457484",
        "publishTime": "2022-02-16T15:03:49.372Z"
      }
    }
  ]
 }

Error message as above, not sure why it's saying the data is not valid JSON?

Additional opinionated question...Should I just be using AlamoFire for this?



Solution 1:[1]

If the json response you show is correct, then in ReceivedMessage change ackID to ackId (note the small "d"), or use

enum CodingKeys: String, CodingKey {
    case ackID = "ackId"
    case message
}

Similarly for messageID in Message.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 workingdog support Ukraine