如何在NSUbiquitousKeyValueStore中存储测量?

How to store Measurement in NSUbiquitousKeyValueStore?

提问人:michal 提问时间:7/11/2023 最后编辑:michal 更新时间:7/11/2023 访问量:28

问:

我有一个对象,我想存储在 中。我之所以使用,是因为我需要定期在各种语言环境之间转换值。Measurement<UnitMass>NSUbiquitousKeyValueStoreMeasurement

我试过扩展.我想下面的代码存在不止一个问题,但我陷入困境的地方是如何处理或转换。(我希望我能在代码中使用 UnitType,这样我就可以在其他测量中重用它来。MeasurementUnitMassUnitType

extension Measurement {
    init(data: NSData) {
        let coding = try? NSKeyedUnarchiver.unarchivedObject(ofClass: Coding.self, from: data as Data)
        self.value = coding?.value as! Double
        self.unit = coding.unit as UnitMass
    }

    func asData() -> NSData {
        return try! NSKeyedArchiver.archivedData(withRootObject: Coding(self), requiringSecureCoding: true) as NSData
    }

    class Coding: NSObject, NSCoding {
        func encode(with coder: NSCoder) {
            coder.encode(value, forKey: "value")
            coder.encode(unit, forKey: "unit")
        }

        let value: NSDecimalNumber
        let unit: NSObject

        init(_ measurement: Measurement) {
            value = NSDecimalNumber(value: measurement.value)
            unit = measurement.unit
        }

        required init?(coder aDecoder: NSCoder) {
            self.value = aDecoder.decodeObject(forKey: "value") as! NSDecimalNumber
            self.unit = aDecoder.decodeObject(forKey: "unit") as! NSObject
        }
    }
}

当然,我的第一次尝试是简单地然后,但是,当然,编译器不知道如何解码它。store.set(weightAsMeasurement, forKey: "weight")store.object(forKey: "Weight") as? Measurement<UnitMass>

我还考虑过将值和单位分开存储。再一次,我被困在单位里。

欢迎任何建议。


编辑:

目前,我决定只存储以下值:

  1. 使用(我使用千克)将测量值转换为显式单位。.converted(to: .kilogram)
  2. 使用 仅存储值。convertedMeasurement.value

从商店阅读时:

  1. 使用 'store.double(forKey: “weight”)' 从存储中读取值。
  2. 使用(或保存到存储区时使用的任何单位)初始化显式选择单位的测量值。Measurement(value: value, unit: UnitMass.kilogram)
  3. 使用measurementInKilogram.converted(to: Locale.current)

有没有更好的方法?

Swift 度量单位 nsubiquitousKeyValueStore

评论


答:

0赞 vadian 7/11/2023 #1

Measurement符合,使用就好了CodableJSONEn-/Decoder

extension Measurement {
    init?(data: Data) {
        do {
            self = try JSONDecoder().decode(Measurement.self, from: data)
        } catch {
            return nil
        }
    }

    func asData() -> Data {
        return try! JSONEncoder().encode(self)
    }
}

评论

0赞 michal 7/12/2023
谢谢。我看到了您的评论,但没有对其进行测试并回复。我会在接下来的几天里尝试一下,让你知道进展如何。