Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将多个对象类型的数组转换为JSON而不丢失Swift中的任何对象属性?_Json_Swift_Encodable - Fatal编程技术网

如何将多个对象类型的数组转换为JSON而不丢失Swift中的任何对象属性?

如何将多个对象类型的数组转换为JSON而不丢失Swift中的任何对象属性?,json,swift,encodable,Json,Swift,Encodable,在iOS Swift项目中,我需要将对象转换为JSON 我有一个简单的课程: 等级车:可编码 { var品牌:字符串 initbrand:String { 自我品牌=品牌 } } 和一个子类: SUVCar类:汽车 { 变量权重:Int 初始重量:Int { 自重 super.initbrand:MyBrand } } 我使用以下通用函数将对象和数组转换为JSON: func toJSON_uu对象:T->String? { 做 { 让jsonEncoder=jsonEncoder 让jsonE

在iOS Swift项目中,我需要将对象转换为JSON

我有一个简单的课程:

等级车:可编码 { var品牌:字符串 initbrand:String { 自我品牌=品牌 } } 和一个子类:

SUVCar类:汽车 { 变量权重:Int 初始重量:Int { 自重 super.initbrand:MyBrand } } 我使用以下通用函数将对象和数组转换为JSON:

func toJSON_uu对象:T->String? { 做 { 让jsonEncoder=jsonEncoder 让jsonEncode=尝试jsonEncoder.encodeobject 返回Stringdata:jsonEncode,编码:.utf8 } 接住 { 归零 } } 现在,假设我想将以下变量转换为JSON:

var arrayOfCars:Array=[] arrayOfCars.appendSUVCar1700 arrayOfCars.appendSUVCar1650 我使用数组作为该数组的类型,因为该数组中还有其他类型的汽车。为了便于阅读,我在这里把它简化了

以下是我所做的:

让json=toJSONarrayOfCars 但出于某种原因,在转换为JSON时,SUVCar的权重属性被忽略,即使arrayOfCars包含SUVCar对象,我得到的JSON如下所示:

[{brand:MyBrand},{brand:MyBrand}] 那么如何在JSON中获得SUVCar的权重属性呢?我错过了什么

谢谢

class SUVCar: Car
{
    enum SUVCarKeys: CodingKey {
        case weight
    }
    var weight: Int

    init(_ weight: Int)
    {
        self.weight = weight
        super.init(brand: "MyBrand")
    }
    
    override func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: SUVCarKeys.self)
        try container.encode(weight, forKey: .weight)
        try super.encode(to: encoder)
    }
}
如果您增加了encode子类的实现,那么您可以添加额外的属性


如果您增加了encode子类的实现,那么您可以添加额外的属性,而不是自定义所有子类来正确编码。您可以通过引入一种容纳不同类型汽车的类型来解决这个问题

struct CarCollection: Encodable {
    let suvs: [SUVCar]
    let jeeps: [Jeep]
    let sedans: [Sedan]
}
假设另外两个子类:吉普车类{}和轿车类{}

这样就不需要额外的代码,编码也就简单了

let cars = CarCollection(suvs: [SUVCar(brand: "x", weight: 1000)],
                         jeeps: [Jeep(brand: "y")],
                         sedans: [Sedan(brand: "z")])

if let json = toJSON(cars) {
    print(json)
}
{吉普车:[{品牌:x}],越野车:[{品牌:x}],轿车:[{品牌:a}]}

有点离题,但在这里,struct可能是比class更好的选择,或者至少它是推荐的选择,所以下面是struct和协议(而不是超类)的外观。上面的代码仍然是一样的

protocol Car : Encodable {
    var brand: String { get set }
}

struct SUVCar : Car {
    var brand: String
    var weight: Int
}

struct Jeep: Car {
    var brand: String
}
struct Sedan: Car {
    var brand: String
}

你可以通过引入一种可以容纳不同类型汽车的类型来解决这个问题,而不是定制所有子类来正确编码

struct CarCollection: Encodable {
    let suvs: [SUVCar]
    let jeeps: [Jeep]
    let sedans: [Sedan]
}
假设另外两个子类:吉普车类{}和轿车类{}

这样就不需要额外的代码,编码也就简单了

let cars = CarCollection(suvs: [SUVCar(brand: "x", weight: 1000)],
                         jeeps: [Jeep(brand: "y")],
                         sedans: [Sedan(brand: "z")])

if let json = toJSON(cars) {
    print(json)
}
{吉普车:[{品牌:x}],越野车:[{品牌:x}],轿车:[{品牌:a}]}

有点离题,但在这里,struct可能是比class更好的选择,或者至少它是推荐的选择,所以下面是struct和协议(而不是超类)的外观。上面的代码仍然是一样的

protocol Car : Encodable {
    var brand: String { get set }
}

struct SUVCar : Car {
    var brand: String
    var weight: Int
}

struct Jeep: Car {
    var brand: String
}
struct Sedan: Car {
    var brand: String
}

你在解码一组汽车,为什么你希望它能解码一组SUVCAR?将数组声明更改为var arrayOfCars:[SUVCar]=[]@LeoDabus好吧,因为它就像Kotlin中的符咒一样工作,所以我期待类似的行为解析解码一个汽车数组为什么希望它解码一个SUVCar数组?将数组声明更改为var arrayOfCars:[SUVCar]=[]@LeoDabus好吧,因为它在Kotlin中像一个符咒一样工作,所以我期待类似的行为Tanks,我会试试。但我对我需要添加的代码数量感到惊讶,在Kotlin和使用Gson库时,我可以在一行代码中完成完全相同的操作…谢谢,我会尝试一下。但我对我需要添加的代码数量感到惊讶,而在Kotlin和使用Gson库时,我可以在一行代码中完成完全相同的操作。。。