Swift codable-如何获取位于层次结构中较高位置的结构的属性值? 试图重构一些遗留JSON解析代码以使用可重用并试图重用现有SWIFT结构,为简单起见,请考虑以下JSON: { "dateOfBirth":"2016-05-19" ... "discountOffer":[ { "discountName":"Discount1" ... }, { "discountName":"Discount2" ... } ] }
在遗留代码中,Swift struct Discount有一个属性'discountType',其值是根据从JSON获得的成员结构的'dateOfBirth'计算的,问题是,如何将成员的dateOfBirth传递给每个折扣结构?或者层次结构中较低的结构是否有办法访问层次结构中较高的结构Swift codable-如何获取位于层次结构中较高位置的结构的属性值? 试图重构一些遗留JSON解析代码以使用可重用并试图重用现有SWIFT结构,为简单起见,请考虑以下JSON: { "dateOfBirth":"2016-05-19" ... "discountOffer":[ { "discountName":"Discount1" ... }, { "discountName":"Discount2" ... } ] },swift,struct,hierarchy,decodable,Swift,Struct,Hierarchy,Decodable,在遗留代码中,Swift struct Discount有一个属性'discountType',其值是根据从JSON获得的成员结构的'dateOfBirth'计算的,问题是,如何将成员的dateOfBirth传递给每个折扣结构?或者层次结构中较低的结构是否有办法访问层次结构中较高的结构 struct Member: Codable { var dateOfBirth: Date? var discounts: [Discount]? } struct Discount: Co
struct Member: Codable {
var dateOfBirth: Date?
var discounts: [Discount]?
}
struct Discount: Codable {
var discountName: String?
var memberDateOfBirth: Date? // *** Need to get it from Member but how?
var discountType: String? // *** Will be determined by Member's dateOfBirth
public init(from decoder: Decoder) throws {
// self.memberDateOfBirth = // *** How to set from Member's dateOfBirth?????
// use self.memberDateOfBirth to determine discountType
...
}
}
我无法使用解码器的userInfo作为get属性。我曾想过将dateOfBirth设置为某个静态变量,但听起来像是一个难题
非常感谢您的帮助。谢谢。您可以这样访问它们
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.memberDateOfBirth = try values.decode(T.self, forKey: .result) //and whatever you want to do
serverErrors = try values.decode([ServerError]?.self, forKey: .serverErrors)
}
您可以这样尝试:
let container = try decoder.container(keyedBy: CodingKeys.self)
let dateString = try container.decode(String.self, forKey: .memberDateOfBirth)
let formatter = "Your Date Formatter"
if let date = formatter.date(from: dateString) {
memberDateOfBirth = date
}
如果您想了解更多信息,请检查此方法:
Dateformatter
,您可以检查:
会员
中处理此问题,而不是折扣
,因为每个可编码
类型都必须能够独立解码
首先,将其添加到折扣中
,以便仅解码名称:
enum CodingKeys : CodingKey {
case discountName
}
然后在成员中执行自定义解码:
enum CodingKeys: CodingKey {
case dateOfBirth, discounts
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
dateOfBirth = try container.decode(Date.self, forKey: .dateOfBirth)
discounts = try container.decode([Discount].self, forKey: .discounts)
for i in 0..<discounts!.count {
discounts![i].memberDateOfBirth = dateOfBirth
}
}
折扣的memberDateOfBirth在折扣的JSON中不可用,我正在尝试使用成员的dateOfBirth设置它,我还需要覆盖init for折扣,因为代码中未显示其他自定义。折扣JSON没有memberDateOfBirth,因此我无法使用编码键映射它,我想使用成员的dateOfBirth设置它,这是JSON树中较高的一个对象。对不起,我以为你想解码日期@清扫者回答得很好,你可以很容易做到。谢谢@Sweeper。坦率地说,这将是未来项目的设计考虑因素,因为一般来说,JSON树中较高级别对象的属性应该由生成JSON的逻辑传播,而不需要客户机代码来传播(除非有令人信服的理由这样做)因为这可能会产生成本,例如在本例中,生成一个循环来创建集合,而不是让可编码框架来完成。再次感谢。
var discountType: String? {
if let dob = memberDateOfBirth {
if dob < Date(timeIntervalSince1970: 0) {
return "Type 1"
}
}
return "Type 2"
}
// or
var memberDateOfBirth: Date? {
didSet {
if let dob = memberDateOfBirth {
if dob < Date(timeIntervalSince1970: 0) {
discountType = "Type 1"
}
}
discountType = "Type 2"
}
}