Units, conversions, and dimensional calculations in Swift Measures 3.0.0

Hi everyone,

I’ve just released version 3.0.0 of Measures, a Swift package for defining, converting, and composing units of measure.

Some of you may remember this discussion from 2023, where I shared an earlier version and explored ideas around measurement APIs. The package has evolved since then, including support for dimensional composition and locale-aware formatting.

Measures provides strongly typed values and units, with SI base and derived units, metric and binary prefixes, and commonly used customary and imperial units. You can also define your own units and dimensions.

For example, you can calculate an area from lengths expressed in different units:

import Measures

let length: Measure<Length> = .init(4, .meter)
let width: Measure<Length> = .init(300, .centimeter)

@Converted(to: .coherent)
var area: Measure<ComposedUnit> = length * width

print(area)
// 12.0 m²

You can multiply, divide, and raise measures to integer powers, then convert the result to a compatible defined unit. The package also supports automatic unit conversion through @Converted and locale-aware formatting through Foundation’s FormatStyle APIs.

Measures requires Swift 6.3 or later.

I’m developing the package independently and would welcome feedback and discussion, particularly about how the API fits calculations you encounter in your own projects.

One area I’m currently researching is decimal floating-point support to address precision issues in measurement calculations. There’s an open issue exploring this, and I’d be interested to hear about others’ experience with decimal or alternative numeric representations.

Repository · Documentation

2 Likes

Here’s another example showing dimensional composition in a calculation: kinetic energy using E = ½mv².

import Measures

let mass: Measure<Mass> = .init(80, .kilogram)
let speed: Measure<Speed> = .init(36, .kilometersPerHour)

let kineticEnergy: Measure<ComposedUnit> = mass * (speed ** 2) / 2

print(kineticEnergy)
// 4000.0 kg·m²·s⁻²

let energy: Measure<Energy> = kineticEnergy.converted(to: .joule)

print(energy)
// 4000.0 J

The calculation handles the conversion from kilometres per hour, squares both the speed and its dimension, and combines the result with mass. You can see the composed unit directly as kg·m²·s⁻², then convert it to a Measure<Energy>expressed in joules.

3 Likes