Swift ObjectMapper: как анализировать массив внутри массива - PullRequest
0 голосов
/ 15 декабря 2018

Это мой ответ JSON:

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

Эта структура JSON получила массив внутри массива, объект внутреннего массива - это то, что я пытаюсь проанализировать.Вот мой маппер:

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"]

    }
}

Я попытался создать еще один маппер struct для хранения массива объектов [JobResponseDataObject] и использовать с ним responseArray Alamofire, но он не работал.Я также попытался поставить префикс моего идентификатора json с 0., но это тоже не сработало.Пожалуйста, помогите

Спасибо

Ответы [ 3 ]

0 голосов
/ 15 декабря 2018

Итак, вот в чем дело ... Codable - это довольно крутой протокол от Apple, предназначенный для анализа ответов JSON от API.То, что вы получаете, - это массив массивов, так что ваши вещи будут выглядеть так:

[[ResponseObject]]

Так что в любом случае вы создадите структуру вашего объекта, например:

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

Заметьте, я немного изменил название ключа (вместо request_id я использовал requestId).Причина в том, что JSONDecoder имеет свойство под названием keyDecodingStrategy, которое представляет перечень стратегий консервированного декодирования, из которых вы можете выбрать.Вы бы сделали convertFromSnakeCase.

Вот код, который вы можете выбросить на игровую площадку, чтобы возиться с ним.По сути, объявите вашу структуру, сопоставьте ее с теми ключами, которые есть в вашем JSON, объявите декодер, передайте ему стратегию декодирования, а затем декодируйте ее.

Вот как можно выполнить вызов Alamofire:

    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)
            }
        }
    }

Вот код, который можно забить на детской площадке.

import UIKit

let json = """
[
    [
        {
        "id": 22,
        "request_id": "rqst5c12fc9e856ae1.06631647",
        "business_name": "Code Viable",
        "business_email": "code@viable.com",
        "title": "Apache Load/Ubuntu",
        }
    ],
    [
        {
        "id": 24,
        "request_id": "rqst5c130cae6f7609.41056231",
        "business_name": "Code Viable",
        "business_email": "code@viable.com",
        "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)
    }
}
0 голосов
/ 15 декабря 2018

Вы должны использовать эту JobResponseDataObject структуру как [[JobResponseDataObject]] вместо [JobResponseDataObject] - когда вы создаете свойство, используя эту структуру в вашей родительской структуре или классе.

0 голосов
/ 15 декабря 2018

Вы можете использовать Codable здесь для отображения ответа JSON, JobResponseDataObject struct должно выглядеть так,

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)
}
...