Measurements and Unitsまとめ

WWDC2016の[Measurements and Units](https://developer.apple.com/videos/play/wwdc2016/238/)、まとめてみました。

こちらは、Foundationに追加された新機能になるので、新しいクラス・構造体の紹介と、
それらをどう組み合わせて使うかという話で全てになります。
新しいクラス・構造体は以下の通りです。

- [Measurement](#measurement)
- [Unit](#unit)
- [Dimension](#dimension)
- [MeasurementFormatter](#measurementformatter)

## Measurement
04:00 - 05:30, 15:30 - 16:00
`Measurement`は、単位を伴う量を示すクラス・構造体です。
そのため、量を示す`value`と単位を表す`unit`をプロパティとして持ちます。
![018.jpeg](https://qiita-image-store.s3.amazonaws.com/0/33395/fd2fbb02-1b6f-5149-8bcb-d2a1e6409826.jpeg)

加減乗除についても、以下のスライドのように行うことができます。
![023.jpeg](https://qiita-image-store.s3.amazonaws.com/0/33395/59d7bd92-0368-2e97-9714-784b36c99da4.jpeg)

## Unit
05:30 - 06:30, 10:30-14:30
`Unit`は単位を表すクラスです。
`Symbol`、`Dimension`、`Equivalence`をプロパティとして持つことができます。
それぞれの意味合いは次の通りです。

|プロパティ|説明|Required or Optional|
|:---|:---|:---|
|Symbol|単位に対応する文字列(m、km、ft...)。|Required|
|Dimension|単位系における次元。|Optional|
|Equivalence|他のDimensionへの変換|Optional|

![031.jpeg](https://qiita-image-store.s3.amazonaws.com/0/33395/59c29e0b-88bc-a143-434c-fc2f1d1177b3.jpeg)

`Dimension`や`Equivalence`がない単位はありうるため、`Unit`の定義は以下の通りになります。
![030.5.jpeg](https://qiita-image-store.s3.amazonaws.com/0/33395/32b3fd58-9db8-5415-c8d1-56f13f88d1d1.jpeg)

## Dimension
06:30 - 10:30, 14:30 - 15:30
`Dimension`は単位系の次元を表すクラスです。
`Dimension`クラスでは、基準となる`Dimension`が存在し、そこから各Dimensionへと変換するという考え方を採用しているため、基準となる`Dimension`である`baseUnit`と、そこからどう変換するかを示すための`converter`を引数として取って初期化を行います。
![041.jpeg](https://qiita-image-store.s3.amazonaws.com/0/33395/b4038f4a-b5d4-55ea-902f-66b03f65d205.jpeg)

`baseUnit`が存在するため、以下のように同じ次元だが別の単位を計算する、といった場合には計算結果は`baseUnit`に変換されます。
![051.jpeg](https://qiita-image-store.s3.amazonaws.com/0/33395/e45b91a2-a731-5146-1aab-29e486616bb1.jpeg)

ちなみに、既に定義されている`Dimension`一覧は下記の通りとなります。
面白いことに、Duration(時間)やLength(距離的な長さ)だけでなく、Illuminance(照度)やFuelEfficiency(燃費)といった、あまり一般的でない単位も定義されています。
![046.jpeg](https://qiita-image-store.s3.amazonaws.com/0/33395/635f7cdb-5725-5108-8c35-1397d56e4179.jpeg)

## MeasurementFormatter
16:00 - 21:30
単位のローカライズをきっちりやろうとすると、かなりタフな仕事になります。
というのも、表記上の単位をローカライズするだけではなく、文化圏に合わせた単位を選択する必要があるためです。
(以下の表では、アメリカのみポンドヤード法の影響でマイル表記となっている)
![101.jpeg](https://qiita-image-store.s3.amazonaws.com/0/33395/a7220e1f-c6c2-5741-6e04-9574534d535f.jpeg)

それを簡易化するために作られたクラスがMeasurementFormatterクラスになります。
これにMeasurementクラスのインスタンスを渡して処理することでローカライズされた適切な値を取得することができます。
![112.jpeg](https://qiita-image-store.s3.amazonaws.com/0/33395/ff6a3462-6871-6c59-1b18-4df9179207ef.jpeg)

また、UnitOptionsに適切な値を渡すことにより、出力結果の単位を様々な形に変更することもできます。
![118.jpeg](https://qiita-image-store.s3.amazonaws.com/0/33395/449536d2-b63f-5fb8-e7e4-f4a0016d99e5.jpeg)


## 参考
- [Measurements and Units](https://developer.apple.com/videos/play/wwdc2016/238/)
- [Measurements and Units(PDF)](http://devstreaming.apple.com/videos/wwdc/2016/238eemv232k9lp2px30/238/238_measurements_and_units.pdf)
- [NSMeasurement Class Reference](https://developer.apple.com/reference/foundation/nsmeasurement)
- [Unit Class Reference](https://developer.apple.com/reference/foundation/nsunit)
- [Dimension Class Reference](https://developer.apple.com/reference/foundation/nsdimension) 
- [MeasurementFormatter Class Reference](https://developer.apple.com/reference/foundation/nsmeasurementformatter)