InkUnits has one main entry point, which is the class UnitConversionEngine
. This class, when instantiated, parses the configuration file (UnitConversions.plist
) containing all conversion factors, and provides two public methods: canConvert from:to:
and convert:from:to
.
The first method checks if a given conversion can be made before attempting it:
func canConvert(from sourceUnits: String, to targetUnits: String) -> Bool
The other method, actually makes the conversion:
func convert(_ amount: Double, from sourceUnits: String, to targetUnits: String) throws -> Double
As instantiating a UnitConversionEngine
parses the configuration file, it is an "expensive" operation, thus it is recommended that you only create one instance of this class for your application. UnitConversionEngine
is not provided as a singleton, so it's your responsibility to make sure only one is created.
UnitConversionEngine
has one parameterless constructor. You instantiate it as follows:
let converter = UnitConversionEngine()
Source and target units are expressed as strings. The units can be simple (e.g. cm) or compound (e.g. kg/cm2). Units follow the following formatting rules:
- Units may have a numerator and denominator, which are separated by a "/" character. For Example:
- kg/cm2
- mi/h
- Compund units with simple units multiplying each other are separated by a "·" character. For Example:
- N·m
- lb·m/s
Sometimes, magnitudes cannot be converted from some source units to other target units. When this is the case, we say that source and target units are inconsistent.
For example, you cannot convert from mi/h to kg/cm3, it simply makes no sense.
This cases may be handled using two different patters:
If you prefer to check whether a certain conversion could happen before attempting it (as opposed to attempting it and handling possible errors), use the following pattern:
if converter.canConvert(from: "N·cm", to: "kN·m")
{
// safe to force try: exceptions won't happen here
try! converter.convert(100, from: "N·cm", to: "kN·m")
}
else
{
// handle inability to convert here
}
If you feel more confortable with handling exceptions, do the following:
do
{
try converter.convert(100, from: "N·cm", to: "kg/m")
}
catch UnitConversionError.inconsistentUnits(let sourceUnits, let targetUnits)
{
// Attempt to recover from conversion exception here
print("Oops! I can't convert from \(sourceUnits) to \(targetUnits)")
}
Or:
do
{
try converter.convert(100, from: "N·cm", to: "kg/m")
}
catch let error as UnitConversionError
{
// Attempt to recover from conversion exception here
print(error.description)
}