Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Save a Generic Measurement<Unit> in Core Data?

How does one save and retrieve a generic Measurement in Core Data?

What I'm looking to do is save either a Measurement<UnitMass> or a Measurement<UnitVolume>.

As can be seen in the image below CoreData is set to accept a Generic Measurement<Unit>

Generic Measurement in Core Data

However I'm getting an error when I go to set the value of the measure. Saying that I'm not allowed to do this. I thought the purpose of generics was to support uses like this.

What am i missing?

enter image description here

like image 666
Aaronium112 Avatar asked Nov 02 '25 12:11

Aaronium112


1 Answers

The error about mismatched types isn't the important part here. The real problem is that transformable attributes only work with classes that conform to NSCoding or for which you've written your own custom value transformer. Since Measurement is not a class and does not conform to NSCoding, you can't use it with a transformable attribute.

Your options are

  1. Don't save the Measurement, save its values, and convert to/from the Measurement when saving/reading property values.
  2. Write your own custom subclass of ValueTransformer that will convert between Measurement and Data.

I'd go with #1. You could add convenience methods on your managed object subclass to handle the conversion.

Update: Using your Measurement<UnitMass> case, I'd do something like:

  • Give the attribute a Double property named massValue.
  • Give the attribute a transformable property named massUnit with custom class UnitMass (see below).
  • Save values with something like this:

    let servingMeasure = Measurement<UnitMass>(value:500, unit:.grams)
    myObject.massValue = servingMeasure.value
    myObject.massUnit = servingMeasure.unit
    
  • Retrieve values with something like:

    if let unit = myObject.massUnit {
        let value = myObject.massValue
        let measurement = Measurement<UnitMass>(value:value, unit:unit)
        print("Measurement: \(measurement)")
    }
    

This is how the massUnit property is configured:

enter image description here

like image 68
Tom Harrington Avatar answered Nov 04 '25 06:11

Tom Harrington



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!