【问题标题】:Swift ObjectMapper: How to parse array inside of an arraySwift ObjectMapper:如何解析数组内的数组
【发布时间】:2019-05-16 07:12:41
【问题描述】:

这是我的 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] 并使用Alamofire 的responseArray,但它不起作用。我也尝试在我的 json id 前面加上 0. ,但这也没有用。请帮忙

谢谢

【问题讨论】:

  • 你没有使用Codable有什么原因吗?
  • 完全没有理由,我使用对象映射器是因为我一直将它用于我的其他映射
  • 酷。 Uno momento...
  • Codable 是更好的选择吗?
  • 我认为这更容易处理,恕我直言。您是否从 API 获取此字符串?

标签: ios json swift alamofire objectmapper


【解决方案1】:

您可以在此处使用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)
}

【讨论】:

  • OP 的问题中没有名为businessModels 的属性,并且您声明的属性不符合Codable
  • 为什么是Int16?此外,如果您的属性名称与 JSON 中的键匹配,则无需声明 CodingKeys 枚举。
【解决方案2】:

这就是交易... Codable 是来自 Apple 的一个非常酷的协议,用于处理来自 API 的解析 JSON 响应。你得到的是一个数组数组,所以你的东西看起来像这样:

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

【讨论】:

    【解决方案3】:

    您应该将此 JobResponseDataObject 结构用作 [[JobResponseDataObject]] 而不是 [JobResponseDataObject] - 您在父结构或类中使用此结构创建属性。

    【讨论】:

      猜你喜欢
      • 2020-01-29
      • 1970-01-01
      • 2017-06-24
      • 2021-09-25
      • 1970-01-01
      • 2015-09-13
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      相关资源
      最近更新 更多