John Doah
John Doah

Reputation: 1999

Getting Invalid type in JSON write (__SwiftValue) trying to create json object

I'm trying to create a json object and post it to a web server. I get this error while trying to upload: Invalid type in JSON write (__SwiftValue), I saw few posts, but they are pretty old or using Alamofire/SwiftyJSON and I'm not, so I couldn't really figure out what the problem was. This is my object:

struct Quantity: Codable {
    var ml: Int
    var price: Float

    init(ml: Int, price: Float) {
        self.ml = ml
        self.price = price
    }
}

struct Product: Codable {
    let uuid: String
    let productName: String
    let productManufacturer: String
    let productImage: String 
    let quantities: [Quantity]
    let additionalInfo: String? 
    let storeID: String
    let storeName: String
    let ownerID: String 

    init(uuid: String, name: String, manufacturer: String, image: String, quantities: [Quantity], additionalInfo: String?, storeID: String, storeName: String, ownerID: String) {
        self.uuid = uuid
        self.productName = name
        self.productManufacturer = manufacturer
        self.productImage = image
        self.quantities = quantities
        self.additionalInfo = additionalInfo
        self.storeID = storeID
        self.storeName = storeName
        self.ownerID = ownerID
    }


}

This is how I'm trying to upload it:

func uploadProduct(product: Product ,completion: @escaping(Error?) -> Void) {
    let jsonObject: [String: Any] = [
        "product_id": product.uuid,
        "name": product.productName,
        "manufacturer": product.productManufacturer,
        "image_url": product.productImage,
        "quantities": product.quantities,
        "additionalInfo": product.additionalInfo ?? "",
        "store_id": product.storeID,
        "store_name": product.storeName,
        "owner_id": product.ownerID,
    ]

    do {
        let jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted)
        //HTTP POST
        guard let url = URL(string: ApplicationURLs.productCreation) else { return }
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = jsonData
        _ = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
            if let error = error {
                completion(error)
                return
            }
            if let response = response as? HTTPURLResponse {
                if response.statusCode == 200 {
                    //Product was added.
                    completion(nil)
                }else {
                    print(response.statusCode)
                    completion(error)
                }
            }
        }).resume()
    }catch { debugPrint("Couldn't create JSON Object...") }
}

I'm not even getting to the catch block, so I don't really know where the error comes from.

Both, Product and Quantity have CodingKeys matching to the json I'm expecting and trying to send, I just removed them from the post to not clutter it.

Upvotes: 0

Views: 744

Answers (1)

Jawad Ali
Jawad Ali

Reputation: 14397

First of all you dont need init in Struct .. Struct has member wise default initialiser so if you dont need to do anything extra (as we are seeing you are not) ... they are already constructed you ca remove that code

struct Quantity: Codable {
    var ml: Int
    var price: Float

}

struct Product: Codable {
    let uuid: String
    let productName: String
    let productManufacturer: String
    let productImage: String 
    let quantities: [Quantity]
    let additionalInfo: String? 
    let storeID: String
    let storeName: String
    let ownerID: String 

}

Then use JSONEncoder to encode your object ...

do {
    let data = try JSONEncoder().encode(Product)
    // use data here
} catch {
    print(error)
}

You dont need to create let jsonObject: [String: Any] to convert product to json

Upvotes: 1

Related Questions