【发布时间】:2021-04-24 01:26:03
【问题描述】:
我正在尝试在Measurement<UnitMass> 和UnitMass 上实现RawRepresentable,以便用@AppStorage 装饰器替换以下代码:
var unitOfMeasure: UnitMass {
get { AppSettings.defaults.string(forKey: "unitOfMeasure").flatMap { UnitMass.fromSymbol(rawValue: $0) }! }
set { AppSettings.defaults.set(newValue.symbol, forKey: "unitOfMeasure") }
}
var weightOverwrite: Measurement<UnitMass> {
get { .init(value: AppSettings.defaults.double(forKey: "weightOverwrite"), unit: unitOfMeasure) }
set { AppSettings.defaults.set(newValue.value, forKey: "weightOverwrite") }
}
我该怎么做?我使用 JSONEncoder/JSONDecoder 实现了它:
extension Measurement: RawRepresentable {
public init?(rawValue: String) {
guard let data = rawValue.data(using: .utf8),
let result = try? JSONDecoder().decode(Measurement.self, from: data)
else {
return nil
}
self = result
}
public var rawValue: String {
guard let data = try? JSONEncoder().encode(self),
let result = String(data: data, encoding: .utf8)
else {
return "{}"
}
return result
}
}
但我没有为 UnitMass 做到这一点:
extension UnitMass: RawRepresentable {
public init?(rawValue: String) {
for unitMass in UnitMass.allCases where rawValue == unitLength.symbol {
self = unitLength
}
return nil
}
}
我收到Designated initializer cannot be declared in an extension of 'UnitMass'。我做错了什么?
【问题讨论】:
-
你需要自己的
UnitMass包装类型,或者放弃使用AppStorage的想法。您不能将UnitMass与RawRepresentable一致。 -
unitOfMeasure的唯一目的似乎是表示weightOverwrite的单位,但weightOverwrite已经是Measurement<UnitMass>,其中包含单位信息。你不是只需要其中一个来符合RawRepresentable吗?您可以将weightOverwrite存储在用户默认值中,unitOfMeasure可以只返回weightOverwrite.unit,对吧? -
有点。计算的属性直接映射到配置 UI。用户可以选择
unitOfMeasure直接影响weightOverwrite的单位。
标签: swift decorator nsuserdefaults