Pheepster
Pheepster

Reputation: 6367

Adding nested dictionary causes JSONSerialization to return nil

I have the following structure that is used to pass JSON data to a REST endpoint. Originally the object contained only one level of key-value pairs. In that scenario, serializing to a JSON object worked properly.

Now I need to add a dictionary as a parameter, which should create a nested dictionary in the resulting JSON. However, adding the nested dictionary causes JSONSerialization to return nil.

Code:

struct ServicePayload:Codable {

    private var name:String
    private var type:String
    private var deviceId:String
    private var clientType:String
    private var appInstanceId:String
    private var version:String
    private var addParams:[String:String] // causes failure

    init(name:String, type:String, version:String, params:[String:String]) {
        self.name = name
        self.type = type
        self.deviceId = Constants.Device.identifier!
        self.version = version
        self.clientType = "1"
        self.appInstanceId = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
        self.addParams = params
    }

    // json mapper
    private enum CodingKeys:String, CodingKey {
        case name = "name"
        case type = "contentTypes"
        case deviceId = "x-DeviceId"
        case clientType = "x-ClientType"
        case appInstanceId = "x-InstanceId"
        case version = "version"
        case addParams = "optionalParams"
    }

    func getJsonObject() -> [String:String]? {
        do {
            let encoded = try JSONEncoder().encode(self)
            if let json = try JSONSerialization.jsonObject(with: encoded, options: []) as? [String : String] {
                return json
            }
        } catch (let error) {
            print("Error building JSON: \(error.localizedDescription)")
        }
        return nil
    }
}

Without the the addParams field, the JSONSerialization works as expected. When I add the addParams field, which adds a nested dictionary to the object, the JSONSerialization fails and returns nil.

Can anyone give me a clue as to why I can't add a nested dictionary in this scenario?

Thanks!

Upvotes: 1

Views: 94

Answers (1)

Shehata Gamal
Shehata Gamal

Reputation: 100541

It fails as one key (here it's the added addParams ) 's value isn't a String so the cast

 as? [String : String] // causes failure

Won't occur , hence a nil json , so Replace

if let json = try JSONSerialization.jsonObject(with: encoded, options: []) 
 as? [String : String] {

with

if let json = try JSONSerialization.jsonObject(with: encoded, options: []) 
 as? [String : Any] {

Any encapsulates String and [String:String]

Upvotes: 1

Related Questions