David Garces
Oct 25, 2016 · 3 min read

In WWDC 2016 Apple introduced a very useful Measurement class which you can use to define units and operations with pre-defined units or creating your own. In this article I share my journey in the creation of a custom unit I used in my most recent project that required calculations using scientific units.


The Measurement class has a simple definition:

Measurement<UnitType : Unit>

Measurement is quite useful if you need to write code that handles data in different units (e.g. km or mi) and you need to do operations or conversions between units. Because most conversions and operations are already handled by the Measurement class, your code will be substantially reduced as you’ll only need to worry about creating the relevant definitions and calling the appropriate methods to perform operations.

Using the Measurement class

If you’ll like to use the existing units that come with Measurement, you’ll only need to know what Unit type you need and the value, then you can easily define a measurement value as follows:

var myMeasurement = Measurement(value: 50, unit: UnitLength.miles)

The compiler will always hold your value and unit information (50 mi) in case you need to do a conversion:

var myKm = myMiles.converted(to: UnitLength.kilometers)

which should give you a value of:

80.467 km

You could also do more complex calculations using different units like:

var myMiles = Measurement(value: 50, unit: UnitLength.miles)var myKm = Measurement(value: 10, unit: UnitLength.kilometers)var myOperation = myMiles + myKm

Xcode will convert the values to a base unit and give you the result in the base unit (in this case 90467.0 m). Do note that base unit is the unit specified by the development team when they designed and wrote the Measurement class.

Measurement uses a new specific subclass of unit called Dimension that holds all the unit types predefined by Apple. I believe this set of units will be expanded in the future, but at the time of writing I found that Apple has managed to include most common unit systems to be used.

Creating a custom measurement and unit

In my project I needed to mostly use Mole for calculations. Unluckily for me, at the time of testing and writing the App, Swift 3 was still in beta and this unit didn't exist yet. The closest unit that Apple has for this measurement is millimoles per litre where you need to specify a concentration of grams per mole:

var myMole = Measurement(value: 10, unit: UnitConcentrationMass.millimolesPerLiter(withGramsPerMole: 12))

For my specific operation I didn't need to work with detailed concentrations like this, but just to make conversions between mole scales, so I decided to create my custom mole unit.

Because this unit belongs to the group of UnitConcentrationMass, I chose to subclass this class to create my custom unit.

When you want to create your own new unit, you need to always define a base unit. In my case I called it molar. I had to add the @nonobjc attribute, because the definition added some kind of conflict with the objective-c compiler (but if it doesn't for you, you can just ignore it). You'll also need a symbol and a converter. The converter is used for operations.

@nonobjc static let molar = UnitConcentrationMass(symbol: "M", converter: UnitConverterLinear(coefficient: 1))

For this unit the converter works in exponential increments of 10 as we increase it, so I decided to create a custom operator as a shortcut:

precedencegroup ExponentiativePrecedence {associativity: righthigherThan: MultiplicationPrecedence}// Put this at file level anywhere in your projectinfix operator ^^: ExponentiativePrecedencepublic func ^^ (radix: Double, power: Double) -> Double {return pow((radix), (power))}

This was with the help of a contribution to my question in StackOverflow about the new precedence group declaration, also introduced in Swift 3 and required for custom Operators. Using ^^ as my shorthand operator, I can write exponential operations in a simpler way, thus my next unit in the scale could be written like this:

@nonobjc static let millimolar = UnitConcentrationMass(symbol: "mM", converter: UnitConverterLinear(coefficient: 10 ^^ -3))

The final class should look like this:

I could then easily use my new unit for operations like:

unitconcentrationmass-molar-example
unitconcentrationmass-molar-example

David codes (swift)

My stories about programming with Swift

David Garces

Written by

Developer, Technologist and Blogger

David codes (swift)

My stories about programming with Swift

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade