Ankur Israni
Ankur Israni

Reputation: 33

'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__SwiftValue)'

I am getting the following error when I try to encode an object.

'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__SwiftValue)'

The definition of this object is as under:-

public struct Item: Codable {
    public var _id: Int
    public var name: String
    public var price: Float

    public init(_id: Int, name: String, price: Float) {
        self._id = _id
        self.name = name
        self.price = price
    }    

    public enum CodingKeys: String, CodingKey {
        case _id = "id"
        case name
        case price
    }
}

And I am trying to encode it by:

public func createDictionaryRequestForAddingItems(item : Item)->Data{
    let dictRequest = ["item":item];
    let dataRequest = try! JSONSerialization.data(withJSONObject: dictRequest, options: []);
    return dataRequest;
}

If instead of an item object I use a simple object like a String or an Int directly, then it all works, but when the request needs an Item object (which IS-A Codable instance) then it gives the above error.

JSONSerialization.isValidJSONObject(item) always gives false, even for the requests that getting properly getting encoded.

Upvotes: 3

Views: 4228

Answers (1)

Sulthan
Sulthan

Reputation: 130201

The problem is that you are trying to combine two types of JSON encoding. JSONSerialization and Codable. JSONSerialization has nothing to do with Codable.

Actually, you want something like this:

public func createDictionaryRequestForAddingItems(item: Item) -> Data {
   let dictRequest = ["item": item]
   let dataRequest = try! JSONEncoder().encode(dictRequest)
   return dataRequest
}

JSONSerialization can encode only the following types: Array, Dictionary, String, Bool and numeric types (e.g. Double, Int).

Upvotes: 4

Related Questions