Custom scientific measurements using the new NSMeasurement class

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 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:

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

which should give you a value of:

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

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:

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.

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:

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:

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

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

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store