首页 > 解决方案 > 将数组编码为 json 时的键顺序问题

问题描述

你好,我是encoding数组,json所以我创建了如下模型类

class QuotationListDataModel: Codable{
    var quatation_id: String?
    var PartNumber: String?
    var Description: String?
    var Quantity: String?
    var AvailableStockQty: String?
    var Each: String?
    init(quatation_id: String?, PartNumber: String?,Description: String?,Quantity:String?,AvailableStockQty: String?,Each: String?) {
        self.quatation_id = quatation_id
        self.PartNumber = PartNumber
        self.Description = Description
        self.Quantity = Quantity
        self.AvailableStockQty = AvailableStockQty
        self.Each = Each
    }

}

我正在编码如下

  let encoder = JSONEncoder()
  encoder.outputFormatting = .prettyPrinted
  do {
       let jsonData = try encoder.encode(quotationSeelctedData)
       if let jsonString = String.init(data: jsonData, encoding: .utf8) {
             print(jsonString)
       }
  } catch {
      print("the encoding failed")
  }

并且使用此代码 json 编码成功,但当我打印编码字符串时未维护顺序,然后我得到如下输出

[
  {
    "quatation_id": "67",
    "Description": "PSH BTN",
    "Each": "140.00 Total 40320.00",
    "PartNumber": "15",
    "Quantity": "288",
    "AvailableStockQty": "0"
  },
  {
    "quatation_id": "66",
    "Description": "SELF-CLOSING 4-ARM HANDLE (PLATED BRASS)",
    "Each": "14.00 Total 3612.00",
    "PartNumber": "000015-40",
    "Quantity": "258",
    "AvailableStockQty": "10"
  }
]

我想输出如下

Part Number : 000015-40

Description : SELF-CLOSING 4-ARM HANDLE (PLATED BRASS)

Quantity : 10

Available Stock Qty. : 10

Each: 12.1 Total: 121

谁能告诉我如何按照我的模型类维护秩序

标签: iosswiftencodingjsonencoder

解决方案


我想,根据上面的评论,您实际上不想订购字典的键,您希望打印版本的顺序如下:

Part Number : 000015-40
Description : SELF-CLOSING 4-ARM HANDLE (PLATED BRASS)
Quantity : 10
Available Stock Qty. : 10
Each: 12.1 Total: 121

所以,我想这里的正确答案是打印如下:

首先,创建包装器

struct FailableDecodable<Base : Decodable> : Decodable {

    let base: Base?

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        self.base = try? container.decode(Base.self)
    }
}

let items = try JSONDecoder()
    .decode([FailableDecodable<QuotationListDataModel>].self, from: json)
    .compactMap { $0.base } // .flatMap in Swift 4.0

       }
  } catch {
      print("the encoding failed")
  }

print(items)

如果您想根据需要打印它们

for item in items {
    print("Part Number : \(item.PartNumber!)" // << you should     handle it if it's nill, so use if let ...
    print("Description : \(item.Description!)"
    print("Quantity : \(item.Quantity!)"
    print("Available Stock Qty. : \(item.AvailableStockQty!)"
    print("Each: \(item.Each!) Total: \(item.AvailableStockQty! * item.Each!)"
}

建议

我建议您遵循 swift 代码标准,并使用防御编程来保护您的函数 - 另外,在您的课程中,不要将可选变量用于必需(重要)信息。

资源:

https://stackoverflow.com/a/46369152/1388852


推荐阅读