I am trying to parse the following JSON using decodable protocol. I am able to parse string value such as roomName. But I am not able to map/parse owners, admins, members keys correctly. For eg, using below code, I can able to parse if the values in owners/members are coming as an array. But in some cases, the response will come as a string value(see owners key in JSON), but I am not able to map string values.
Note: Values of admins, members, owners can be string or array (see owners and members keys in JSON)
{
"roomName": "6f9259d5-62d0-3476-6601-8c284a0b7dde",
"owners": {
"owner": "anish@local.mac" //This can be array or string
},
"admins": null, //This can be array or string
"members": {
"member": [ //This can be array or string
"steve@local.mac",
"mahe@local.mac"
]
}
}
Model:
struct ChatRoom: Codable{
var roomName: String! = ""
var owners: Owners? = nil
var members: Members? = nil
var admins: Admins? = nil
enum RoomKeys: String, CodingKey {
case roomName
case owners
case members
case admins
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: RoomKeys.self)
roomName = try container.decode(String.self, forKey: .roomName)
if let member = try? container.decode(Members.self, forKey: .members) {
members = member
}
if let owner = try? container.decode(Owners.self, forKey: .owners) {
owners = owner
}
if let admin = try? container.decode(Admins.self, forKey: .admins) {
admins = admin
}
}
}
//Owner Model
struct Owners:Codable{
var owner: AnyObject?
enum OwnerKeys:String,CodingKey {
case owner
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: OwnerKeys.self)
if let ownerValue = try container.decodeIfPresent([String].self, forKey: .owner){
owner = ownerValue as AnyObject
}
else{
owner = try? container.decode(String.self, forKey: .owner) as AnyObject
}
}
func encode(to encoder: Encoder) throws {
}
}
//Member Model
struct Members:Codable{
var member:AnyObject?
enum MemberKeys:String,CodingKey {
case member
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: MemberKeys.self)
if let memberValue = try container.decodeIfPresent([String].self, forKey: .member){
member = memberValue as AnyObject
}
else{
member = try? container.decode(String.self, forKey: .member) as AnyObject
}
}
func encode(to encoder: Encoder) throws {
}
}