Skip to content
This repository has been archived by the owner on Jul 10, 2024. It is now read-only.
/ MKUnits Public archive
forked from michalkonturek/MKUnits

Unit conversion library for Objective-C.

License

Notifications You must be signed in to change notification settings

WahooFitness/MKUnits

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MKUnits

Twitter License CocoaPods Build Status

MKUnits is extremely precise unit conversion library for Objective-C. It provides units of measurement of physical quantities and simplifies manipulation of them.

License

Source code of this project is available under the standard MIT license. Please see the license file.

Example

Let's create 1.5 kilograms [kg],

id kilograms = [@1.5 mass_kilogram];

0.5 [kg] in grams [g]

id grams = [@500 mass_gram];

and 10 pounds [lb] (which is 4.5359237 [kg])

id pounds = [@10 mass_pound];

Then we add all of the above togehter and subtract 0.0001 [kg] in milligrams [mg].

id milligrams = [@100 mass_milligram];
id result = [[[kilograms add:grams] add:pounds] subtract:milligrams];

The result amount is 6.5358237 [kg].

Now we subtract 0.5358237 [kg] in ounces [oz], which is 18.900624805 [oz] according to Google converter, but as MKUnits is very precise, it is in fact 18.900624805483390296005199558361177 [oz].

id ounces = [[@0.5358237 mass_kilogram] convertTo:[MKMassUnit ounce]];
result = [result subtract:ounces];

The result amount is ~6 [kg]; 6.00000000000000000000000000000000003 [kg] to be exact.

Now we want the result to be in stones [st], so:

result = [result convertTo:[MKMassUnit stone]];
// 0.94483873964811055873038869091017890993 st

As the result is too precise for our needs, we want to round it.

We can do that by either creating new MKQuantity object with rounded amount,

id stone_quantity = [result quantityWithPrecision:3];
// 0.945 st

or by rounding the amount of existing MKQuantity.

id amount_in_stones_1 = [result amountWithPrecision:3];
// 0.945

id amount_in_stones_2 = [[result amount] mk_roundedWithPrecision:3];;
// 0.945

Swift Integration

MKUnits works with Swift.

let kilograms = NSNumber.mass_kilogram(2)()
let pounds = NSNumber.mass_pound(10)()
let result = kilograms.add(pounds)
println(result)

You can also integrate imported Objective-C classes with Swift types. For example, by creating an extension for Int:

extension Int {

    func mass_kilogram() -> MKQuantity {
        return MKQuantity.mass_kilogramWithAmount(self)
    }

    func mass_pound() -> MKQuantity {
        return MKQuantity.mass_poundWithAmount(self)
    }
}

and then you can do something like that:

let kilograms = 2.mass_kilogram()
let pounds = 10.mass_pound()
let result = kilograms.add(pounds)
println(result)

For Cocoapods Integration with Swift please refer to the my blog post Integrating Cocoapods with a Swift project.

Supported Quantities

At the moment MKUnits supports the following quantities:

  • Area (base unit: square meter)
  • Bytes (base unit: bit)
  • Mass (base unit: kilogram)
  • Length (base unit: meter)
  • Time (base unit: second)
  • Volume (base unit: litre)

You can easily extend MKUnits by adding new quantities or units.

Quick Conversion

MKUnits supports quick number conversion between different units without the need of instantiating MKQuantity objects.

Converting amount of 1 [kg] to 1000 [g] can be achieved in the following ways:

id amount = [MKUnit convertAmount:@1 from:[MKMassUnit kilogram] to:[MKMassUnit gram]];

id amount = [[MKMassUnit kilogram] convertAmount:@1 to:[MKMassUnit gram]];

id amount = [[MKMassUnit gram] convertAmount:@1 from:[MKMassUnit kilogram]];

Precision and Rounding

MKUnits uses NSDecimalNumber for all operations, therefore, it is extremely precise.

To round a number to a desired decimal place, simply use mk_roundedWithPrecision: method of NSNumber+MK_Precision category.

Example: Rounding 1.123456789 to 5 decimal places:

[@1.123456789 mk_roundedWithPrecision:5]; // results in 1.12346.

Alternatively you can take advantage of MKQuantity+Precision category which offers the following methods:

- (instancetype)quantityWithPrecision:(short)precision;
- (NSNumber *)amountWithPrecision:(short)precision;

- (BOOL)isTheSame:(MKQuantity *)other withPrecision:(short)precision;
- (BOOL)isGreaterThan:(MKQuantity *)other withPrecision:(short)precision;
- (BOOL)isLessThan:(MKQuantity *)other withPrecision:(short)precision;

- (NSComparisonResult)compare:(MKQuantity *)other withPrecision:(short)precision;

Extending MKUnits

Adding new Quantity

In order to add new Quantity simply create a class that extends MKUnit and follow the convention below.

Please make sure that unit symbols are unique across your Quantity.

Example .h file:

@interface QuantityUnit : MKUnit

+ (instancetype)unit_one;
+ (instancetype)unit_two;

@end

@interface MKQuantity (QuantityUnit)

+ (instancetype)quantity_unitoneWithAmount:(NSNumber *)amount;
+ (instancetype)quantity_unittwoWithAmount:(NSNumber *)amount;

@end

@interface NSNumber (QuantityUnit)

- (MKQuantity *)quantity_unitone;
- (MKQuantity *)quantity_unittwo;

@end

Example .m file:

@implementation QuantityUnit : MKUnit

+ (instancetype)unit_one {
    static NSString *name   = @"unit_one";
    static NSString *symbol = @"u1";
    id ratio = [NSDecimalNumber one]; // as it is a base unit
    
    return [self createWithName:name
                     withSymbol:symbol
                      withRatio:ratio];
}

+ (instancetype)unit_two {
    static NSString *name   = @"unit_two";
    static NSString *symbol = @"u2";
    id ratio = [NSDecimalNumber decimalNumberWithMantissa:2 exponent:0 isNegative:NO];
    
    return [self createWithName:name
                     withSymbol:symbol
                      withRatio:ratio];
}

@end

@implementation MKQuantity (QuantityUnit)

+ (instancetype)quantity_unitoneWithAmount:(NSNumber *)amount {
	return [self createWithAmount:amount withUnit:[QuantityUnit unit_one]];
}

+ (instancetype)quantity_unittwoWithAmount:(NSNumber *)amount {
	return [self createWithAmount:amount withUnit:[QuantityUnit unit_two]];
}

@end

@implementation NSNumber (QuantityUnit)

- (MKQuantity *)quantity_unitone {
	return [MKQuantity quantity_unitoneWithAmount:self];
}

- (MKQuantity *)quantity_unittwo {
	return [MKQuantity quantity_unittwoWithAmount:self];
}

@end

Adding new Unit to existing Quantity

To add additional units to existing Quantity simply create a category for that Quantity.

Do not sublcass as units are only interconvertible with units belonging to the same Quantity.

Example .h file:

@interface GroupUnit (Extension)

+ (instancetype)unit_one;
+ (instancetype)unit_two;

@end

@interface MKQuantity (GroupUnit_Extension)

+ (instancetype)group_unitoneWithAmount:(NSNumber *)amount;
+ (instancetype)group_unittwoWithAmount:(NSNumber *)amount;

@end

@interface NSNumber (GroupUnit_Extension)

- (MKQuantity *)quantity_unitone;
- (MKQuantity *)quantity_unittwo;

@end

Contributing

  1. Fork it.
  2. Create your feature branch (git checkout -b new-feature).
  3. Commit your changes (git commit -am 'Added new-feature').
  4. Push to the branch (git push origin new-feature).
  5. Create new Pull Request.

About

Unit conversion library for Objective-C.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Objective-C 97.2%
  • Shell 2.3%
  • Other 0.5%