Shakti
Shakti

Reputation: 996

How to handle dynamic keys from json response using Swift 4 coding keys

In my app i am getting the response like this how i will handle this kind of response which has this which has dynamic keys in every data array

{
    "code": 200,
    "message": "Top Likers info.",
    "error": null,
    "data": {
        "manishamohapatra11": {
            "id": "5591322611",
            "username": "manishamohapatra11",
            "full_name": ":-)Sunshine :-)",
            "profile_pic_url": "https://scontent-atl3-1.cdninstagram.com/vp/d2ba431ac70ec067d5d6def73a721250/5B553C8E/t51.2885-19/s150x150/27877706_168319037141873_8387886458379173888_n.jpg",
            "followed_by_viewer": true,
            "requested_by_viewer": false,
            "likeCount": 7
        },
        "chrysxnthemxm": {
            "id": "5658970660",
            "username": "chrysxnthemxm",
            "full_name": "Quotes and Sayings",
            "profile_pic_url": "https://scontent-atl3-1.cdninstagram.com/vp/f1fb37c94c181d49d9997e24b5d70068/5B40EF01/t51.2885-19/s150x150/20478547_331538517270771_7021810425566068736_a.jpg",
            "followed_by_viewer": true,
            "requested_by_viewer": false,
            "likeCount": 4
        }
     }
   }

i have created structure response

Upvotes: 3

Views: 2964

Answers (2)

Code Different
Code Different

Reputation: 93161

// A struct that conforms to the CodingKey protocol
// It defines no key by itself, hence the name "Generic"
struct GenericCodingKeys: CodingKey {
    var stringValue: String
    var intValue: Int?

    init?(stringValue: String) { self.stringValue = stringValue }
    init?(intValue: Int) { self.intValue = intValue; self.stringValue = "\(intValue)" }
}

struct Response: Decodable {

    // Define the inner model as usual
    struct User: Decodable {
        var id: String
        var userName: String
        var fullName: String
        var profilePicURL: URL
        var followedByViewer: Bool
        var requestedByViewer: Bool
        var likeCount: Int

        private enum CodingKeys: String, CodingKey {
            case id
            case userName          = "username"
            case fullName          = "full_name"
            case profilePicURL     = "profile_pic_url"
            case followedByViewer  = "followed_by_viewer"
            case requestedByViewer = "requested_by_viewer"
            case likeCount
        }
    }

    var code: Int
    var message: String
    var error: String?
    var users: [User]

    private enum CodingKeys: String, CodingKey {
        case code, message, error, data
    }

    // You must decode the JSON manually
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.code     = try container.decode(Int.self, forKey: .code)
        self.message  = try container.decode(String.self, forKey: .message)
        self.error    = try container.decodeIfPresent(String.self, forKey: .error)

        self.users = [User]()
        let subContainer = try container.nestedContainer(keyedBy: GenericCodingKeys.self, forKey: .data)
        for key in subContainer.allKeys {
            let user = try subContainer.decode(User.self, forKey: key)
            self.users.append(user)
        }
    }
}

Upvotes: 6

Chirag Sondagar
Chirag Sondagar

Reputation: 619

You can try this type...

let arrTemp:NSArray = data.allKeys as NSArray
        print(arrTemp)

        let strData:NSDictionary = param.value(forKey: arrTemp.object(at: index) as! String) as! NSDictionary
        print(strData)

Upvotes: -1

Related Questions