Unit conversion is easy in Swift
Foundation
framework has many useful implementations, that can make our life easier. One of them is Unit and Measurement APIs.
Unit and Measurement
Measurment
is a struct that holds the value of the given Unit
. Additionally, it can convert, add, subtract, and do other arithmetical operations on this value. The best thing is, that it will do conversions for you!
UnitLength
One of the available types of Unit
is UnitLength
. It can represent any length value you can imagine, even famous from Star Wars - Parsec! How awesome is that?
We can use our length units to quickly create a unit converter calculator! For simplicity, we will just do a small exercise to convert some "EU" types to "US" types.
So how we can do that?
let lengthInCentimeters = Measurement(value: 100, unit: UnitLength.centimeters)
let lengthInFeet = lengthInCentimeters.converted(to: .feet)
print(lengthInFeet)
// prints 3.280839895013123 ft
And that's it! Since this API uses something called phantom types, we don't have to worry about conversion safety. .centimeters
and .feet
are both UnitLength
. Additionally, all units have their own symbols, baked in! So you don't even have to worry about remembering symbols, at all!
Apple provides more than 20 dimensions, and every dimension defines most of the popular units, so you are covered with 99% of possibilities out of the box!
Custom units
What if there is something missing? Or do you want to create something "unusual"? No problem!
Liters per 100 Miles
Let's make a mix of "EU" fuel efficiency with "US" fuel efficiency - Liters per 100 Miles. Apple gives us dimension for fuel efficiency UnitFuelEfficiency
.
We have to create a dimension, that is UnitFuelEfficiency
:
extension UnitFuelEfficiency {
static var litersPer100Miles: UnitFuelEfficiency {
UnitFuelEfficiency(
symbol: "l/100mi",
converter: UnitConverterLinear(coefficient: 1/1.60934)
)
}
}
This couple of lines make it possible. The only thing that is really important is the converter. The converter is responsible for converting our new unit to the base unit of a given dimension, in our case is .litersPer100Kilometers
.
Conversion
Let's use our new unit to convert fuel efficiency!
let litersPer100Kilometers = Measurement(value: 10, unit: UnitFuelEfficiency.litersPer100Kilometers)
let litersPer100Miles = litersPer100Kilometers.converted(to: .litersPer100Miles)
print(litersPer100Miles) // prints 16.0934 l/100mi
let mpg = litersPer100Miles.converted(to: .milesPerGallon)
let mpgFromliters = litersPer100Kilometers.converted(to: .milesPerGallon)
print(mpg) // prints 23.5215 mpg
print(mpgFromliters) // prints 23.5215 mpg
It works! Automatically it can convert to the base unit, but also it converts to other fuel efficiency units! How awesome is that! But what about arithmetics?
print(litersPer100Kilometers + litersPer100Miles) // prints 20.0 L/100km
Wow! Operators work for free, automatically converting between different units, and adding them properly!
I hope you like it and learn something!