SwiftData won't work with Measurement types

I'm trying out SwiftData and converting my existing data models using Structs and Codable to Classes and SwiftData. I've got a model that has a Measurement<UnitMass> type. When I run the app after converting everything to use classes with the @Model macro, I get a fatal error: SwiftData/SchemaProperty.swift:325: Fatal error: Unexpected type for CompositeAttribute: NSUnitMass.

Since Measurement conforms to Codable, and SwiftData should work with Codable types, why is this not working?

I also tried marking the property with @Attribute(.transformable) and it didn't make a difference.

I am also having this problem with NSSecureCoding. I suspect it's a problem with existentials. I agree that it is a bug -- they should be hidden behind the Codable interface.

An AttributedString field on a @Model class similarly results in Unexpected type for CompositeAttribute: Guts

Similar error with Measurement<UnitDuration> reported as, Fatal error: Unexpected type for CompositeAttribute: NSUnitDuration.

Issue still exists on Beta 7

Issue still exists on Beta 8

I ran into the same issue. A work around I found is to use Measurement in an @Transient and convert it to a Double for storage. This lets me work with Measurements in my views, but stores it as a Double which SwiftData can handle.

You want to store your data all as the same measurement system type (metric, US or UK) so you know what you're working with. I store everything in metric and then let the system convert it locale measurement system for display. If you have the user input measurement data, saving requires a little more work since you have to know what locale the user is in in order to do the correct conversion to metric for storage. Use @Environment(.locale) to get the user's measurement system and then use the built in measurement conversions to convert it to the storage unit. This post has a nice extension for getting the user Locale. https://stackoverflow.com/questions/50914297/get-value-of-localized-unit-from-measurement

var widthMaxMeters: Double? = nil

@Transient var widthMax: Measurement<UnitLength>? {
            get {
                if let widthMaxMeters {
                    return Measurement<UnitLength>(value: widthMaxMeters, unit: .meters)
                } else { return nil }
            }
            set { widthMaxMeters = newValue?.value}
}

I am getting a similar crash

SwiftData/DataUtilities.swift:1140: Fatal error: Unexpected type for Expansion: Optional<UIColor>

But this is for a transformable property in my model that is a UIColor, it's happening for me in Xcode 15 RC

Issue still exists on 15.1 Beta 3

UIColor is not Codable, which @Model requires. It is not a bug. You can use the technique above to save the rgba values as a string or floats, which are Codable.

Still an issue in Xcode 16.0 beta (16A5171c)

SwiftData won't work with Measurement types
 
 
Q