Kerim Khasbulatov
Kerim Khasbulatov

Reputation: 722

swifty json parse array object

how can I set an array of Images to an images variable of the Car class

my json:

{
    "Description": "test comment",
    "GalleryId": 5548,
    "ShortCode": "rzswig",
    "Images": [
        {
            "Id": 9742,
            "Link": "https://url/Images/5548/image9742_x560.jpg"
        },
        {
            "Id": 9749,
            "Link": "https://url/Images/5548/image9749_x560.jpg"
        },
        {
            "Id": 9746,
            "Link": "https://url/Images/5548/image9746_x560.jpg"
        }
    ]
}

my class :

class Car: Hashable {
    var shortCode: String
    var description: String
    var galleryId: Int
    var imageItems: [ImageItem]?

    init(response: JSON) {
        shortCode = response["ShortCode"].stringValue        
        description = response["Description"].stringValue
        galleryId = response["GalleryId"].intValue
        imageItems = response["Images"].arrayObject.map {$0} as? [ImageItem]
    }
    
    init(shortCode: String, description: String, galleryId: Int, imageItems: [ImageItem]?) {
        self.description = description
        self.shortCode = shortCode
        self.galleryId = galleryId
        self.imageItems = imageItems
    }
}

struct ImageItem {
    var id: Int
    var link: String
}

variant:

    imageItems = response["Images"].arrayObject.map {$0} as? [ImageItem]

doesn't work for me

Upvotes: 1

Views: 333

Answers (3)

theEagleDev
theEagleDev

Reputation: 15

try response["images"].arrayValue

Upvotes: 0

Sweeper
Sweeper

Reputation: 270995

If you want to keep using SwiftyJSON, you can add an initialiser to ImageItem that takes a JSON, just like you did with Car:

init(response: JSON) {
    id = response["Id"].intValue
    link = response["Link"].stringValue
}

You might also want to add the autogenerated member wise initialiser back if you want it.

Then, to initialise imageItems, do:

imageItems = response["Images"].array?.map(ImageItem.init(response:))

This whole thing would be a lot easier if you used the Codable API built in to Swift.

Just conform both Car and ImageItem to Codable:

class Car: Codable {
    var shortCode: String
    var description: String
    var galleryId: Int
    var imageItems: [ImageItem]?
    
    enum CodingKeys: String, CodingKey {
        case shortCode = "ShortCode"
        case description = "Description"
        case galleryId = "GalleryId"
        case imageItems = "Images"
    }
}

struct ImageItem: Codable {
    var id: Int
    var link: String
    
    enum CodingKeys: String, CodingKey {
        case id = "Id"
        case link = "Link"
    }
}

And then do this to deserialise the json:

let car = JSONDecoder().decode(Car.self, data: jsonData) // jsonData is of type "Data"

Upvotes: 2

goat_herd
goat_herd

Reputation: 589

I think the problem is that you map it as array of Image item

imageItems = response["Images"].arrayObject.map {$0} as? ImageItem

Upvotes: -1

Related Questions