2

This is my JSON response:

[
    [
        {
            "id": 22,
            "request_id": "rqst5c12fc9e856ae1.06631647",
            "business_name": "Code Viable",
            "business_email": "[email protected]",
            "title": "Apache Load/Ubuntu",
        }
    ],
    [
        {
            "id": 24,
            "request_id": "rqst5c130cae6f7609.41056231",
            "business_name": "Code Viable",
            "business_email": "[email protected]",
            "title": "Load",
        }
    ]
]

This JSON structure got an array inside of an array, the object of the inner array is what I am trying to parse. Here is the my mapper:

struct JobResponseDataObject: Mappable {

    init?(map: Map) {

    }

    var id: Int?
    var requestId: String?
    var businessName: String?
    var businessEmail: String?

    mutating func mapping(map: Map) {

        id              <- map["id"]
        requestId       <- map["request_id"]
        businessName    <- map["business_name"]
        businessEmail   <- map["business_email"]

    }
}

I have tried create another mapper struct to hold the array of objects [JobResponseDataObject] and use Alamofire's responseArray with it, but it didn't work. I have also tried prefixing my json id with 0. but that didn't work too. Please help

Thank

8
  • Is there a reason you're not using Codable? Commented Dec 15, 2018 at 4:22
  • No reason at all, I use object mapper because I've been using it for my other mapping Commented Dec 15, 2018 at 4:24
  • Cool. Uno momento... Commented Dec 15, 2018 at 4:25
  • is Codable a better choice here? Commented Dec 15, 2018 at 4:28
  • I think it's easier to handle, IMHO. Are you getting this string from an API? Commented Dec 15, 2018 at 4:28

3 Answers 3

3

So here's the deal...Codable is a pretty cool protocol from Apple to handle parsing JSON responses from APIs. What you're getting back is an array of arrays, so your stuff's gonna be look like this:

[[ResponseObject]]

So anyway, you'd make a struct of your object, like so:

struct ResponseObject: Codable {
    let id: Int?
    let requestId: String?
    let businessName: String?
    let businessEmail: String?
    let title: String?
}

You'll note I changed the key name a bit (instead of request_id, I used requestId). The reason is JSONDecoder has a property called keyDecodingStrategy which presents an enum of canned decoding strategies you can select from. You'd do convertFromSnakeCase.

Here's code you can dump into a playground to tinker with. Basically, declare your struct, match it up to whatever the keys are in your JSON, declare a decoder, feed it a decoding strategy, and then decode it.

Here's how you could do an Alamofire call:

    private let backgroundThread = DispatchQueue(label: "background",
                                                 qos: .userInitiated,
                                                 attributes: .concurrent,
                                                 autoreleaseFrequency: .inherit,
                                                 target: nil)


    Alamofire.request(url).responseJSON(queue: backgroundThread) { (response) in
        guard response.result.error == nil else {
            print("💥KABOOM!💥")
            return
        }

        if let data = response.data {
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase

            do {
                let parsedResponse = try decoder.decode([[ResponseObject]].self, from: data)
                print(parsedResponse)
            } catch {
                print(error.localizedDescription)
            }
        }
    }

Here's code you can chuck in a playground.

import UIKit

let json = """
[
    [
        {
        "id": 22,
        "request_id": "rqst5c12fc9e856ae1.06631647",
        "business_name": "Code Viable",
        "business_email": "[email protected]",
        "title": "Apache Load/Ubuntu",
        }
    ],
    [
        {
        "id": 24,
        "request_id": "rqst5c130cae6f7609.41056231",
        "business_name": "Code Viable",
        "business_email": "[email protected]",
        "title": "Load",
        }
    ]
]
"""

struct ResponseObject: Codable {
    let id: Int?
    let requestId: String?
    let businessName: String?
    let businessEmail: String?
    let title: String?
}

if let data = json.data(using: .utf8) {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase

    do {
        let parsedResponse = try decoder.decode([[ResponseObject]].self, from: data)
        print(parsedResponse)
    } catch {
        print(error.localizedDescription)
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

You should use this JobResponseDataObject struct as [[JobResponseDataObject]] instead of [JobResponseDataObject] - where you are making a property using this struct in your parent struct or class.

Comments

-1

You can use Codable here for mapping the JSON response, The JobResponseDataObject struct should look like,

struct JobResponseDataObject: Codable {
    var id: Int?
    var requestId: String?
    var businessName: String?
    var businessEmail: String?
    var title: String?

    private enum CodingKeys: String, CodingKey {
        case id = "id"
        case requestId = "request_id"
        case businessName = "business_name"
        case businessEmail = "business_email"
        case title = "title"
    }
}

let json = JSON(responseJSON: jsonData)
    do {
        if let value = try? json.rawData(){
            let response = try! JSONDecoder().decode([[JobResponseDataObject]].self, from: value)
        }

    } catch {
        print(error.localizedDescription)
}

2 Comments

There's no property called businessModels in the OP's question and the one you've declared doesn't conform to Codable.
Why Int16? Also, you don’t need to declare the CodingKeys enum if your property names match the keys in JSON.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.