编码嵌套对象

时间:2018-05-15 13:12:00

标签: json swift struct encoding

我有PalletScanHelper类,有两个结构 - MovementScan和PalletScan。

class PalletScanHelper {

    struct MovementScan: Codable {
        var locationId: String?
        var palletId: String?
        var palletType: String?
        var timestamp: String?

        enum CodingKeys: String, CodingKey {
            case locationId = "LocationId"
            case palletId = "PalletId"
            case palletType = "PalletType"
            case timestamp = "TimeStamp"
        }

        enum MovementScanKeys: String, CodingKey {
            case locationId = "locationId"
            case palletId = "palletId"
            case palletType = "palletType"
            case timestamp = "timestamp"
        }

        init(locationId: String, palletId: String, palletType: String, timestammp: String ){
            self.locationId = locationId
            self.palletId = palletId
            self.palletType = palletType
            self.timestamp = timestammp
        }

        init(){
            self.locationId = nil
            self.palletId = nil
            self.palletType = nil
            self.timestamp = nil
        }

        //overide required for JSon to work
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: MovementScanKeys.self)
            let locationId: String =  try values.decode(String.self, forKey: .locationId)
            let palletId: String =  try values.decode(String.self, forKey: .palletId)
            let palletType: String =  try values.decode(String.self, forKey: .palletType)
            let timestamp: String =  try values.decode(String.self, forKey: .timestamp)

            self.init(locationId: locationId, palletId: palletId, palletType: palletType, timestammp: timestamp)
        }

        func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: MovementScanKeys.self)

            try container.encode(locationId, forKey: .locationId)
            try container.encode(palletId, forKey: .palletId)
            try container.encode(palletType, forKey: .palletType)
            try container.encode(timestamp, forKey: .timestamp)

            print("Encoded container: ", container)
        }

    }

    struct PalletScan: Codable {
        var deliveryId: String?
        var userId: String?
        var timestamp: String?
        var tempPalletNr: String?
        var tempLocation: String?
        var tempPalletType: String?
        var pallets: [MovementScan] = [MovementScan]()

        //coding keys requried for translation API -> struct -> CoreData and CoreData -> struct -> API
        enum CodingKeys: String, CodingKey {
            case deliveryId = "TOID"
            case userId = "UserId"
            case timestamp = "TimeStamp"
        }

        init(deliveryId: String, userId: String, timestamp: String, movementScans: [MovementScan]) {
            self.deliveryId = deliveryId
            self.userId = userId
            self.timestamp = timestamp
            for item in movementScans {
                self.pallets.append(item)
                print(item)
            }
        }

        init(deliveryId: String, userId: String, timestamp: String, tempPalletType: String, tempLocation: String, tempPalletNr: String) {
            self.deliveryId = deliveryId
            self.userId = userId
            self.timestamp = timestamp
            self.tempPalletType = tempPalletType
            self.tempLocation = tempLocation
            self.tempPalletNr = tempPalletNr
        }

        init() {
            self.deliveryId = nil
            self.userId = nil
            self.timestamp = nil
            self.pallets = []
        }
}

MovementScan嵌套在托盘扫描中。 MovementScan的编码工作正常,获得正确的JSON字符串。 但是,当想要编码托盘扫描时,没有将嵌套的MovementScan对象编码为JSON。

 do {
                //req.httpBody = try encoder.encode(self)
                let jsonData = try encoder.encode(self)
                let jsonString = String(data: jsonData, encoding: .utf8)
                print (jsonString)
            } catch {
                //TODO:error handling
            }

仅编码主要的PalletScan项目,而MovementScan根本不编码。 我应该将MovementScan编码器放在父PalletScan结构中吗?

1 个答案:

答案 0 :(得分:0)

您的PalletScan缺少一些编码密钥,即使您没有映射所有密钥,也需要将它们全部列出:

     enum CodingKeys: String, CodingKey {
        case tempPalletNr, tempLocation, tempPalletType, pallets
        case deliveryId = "TOID"
        case userId = "UserId"
        case timestamp = "TimeStamp"
    }

P.S。你的代码示例错过了PalletScan struct的结束括号。

相关问题