Page 1
© 2016 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.
Using locale-appropriate measurements in your app
App Frameworks #WWDC16
Session 238
Measurements and Units
Daphne Larose Software Engineer, Foundation
Page 2
Introduction
Measurements pop up all the timeMeasurements should be in preferred unitsNew API makes it easy to do the right thing for everyone
Page 3
Jammin’ in the Streetz
Page 5
Goals
FunLots of emojisAvailable in multiple countries
Page 6
Key Elements of the Game
Jam sessionsTracks• Total time• Distance traveled• Number of dance movements performed• Rate of travel
Page 7
Key Elements of the Game
Jam sessionsTracks• Total time• Distance traveled• Number of dance movements performed• Rate of travel
Page 14
Creating Measurements Easily
Page 15
NEW// Measurement
public struct Measurement<UnitType : Unit> : Comparable, Equatable {
Page 16
NEW// Measurement
public struct Measurement<UnitType : Unit> : Comparable, Equatable {
public let unit: UnitType
Page 17
NEW// Measurement
public struct Measurement<UnitType : Unit> : Comparable, Equatable {
public let unit: UnitType
public var value: Double
Page 18
NEW// Measurement
public struct Measurement<UnitType : Unit> : Comparable, Equatable {
public let unit: UnitType
public var value: Double
public init(value: Double, unit: UnitType)
}
Page 19
! Distance to go Distance traveled
Page 20
// Calculations With Measurements
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
Page 21
// Calculations With Measurements
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
Page 22
// Calculations With Measurements
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
let totalDistance = distanceTraveled + distanceToGo
Page 23
// Calculations With Measurements
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
let totalDistance = distanceTraveled + distanceToGo
value: 11, unit: .feet
Page 24
// Calculations With Measurements
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
let totalDistance = distanceTraveled + distanceToGo
let tripleDistance = 3 * distanceToGo
Page 25
// Calculations With Measurements
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
let totalDistance = distanceTraveled + distanceToGo
let tripleDistance = 3 * distanceToGo
value: 18, unit: .feet
Page 26
// Calculations With Measurements
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
let totalDistance = distanceTraveled + distanceToGo
let tripleDistance = 3 * distanceToGo
let halfDistance = distanceToGo / 2
Page 27
// Calculations With Measurements
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
let totalDistance = distanceTraveled + distanceToGo
let tripleDistance = 3 * distanceToGo
let halfDistance = distanceToGo / 2
value: 3, unit: .feet
Page 28
Properties of a Unit
Page 29
Properties of a Unit
Symbol “ft”
Page 30
Properties of a Unit
Symbol “ft”
Dimension “Foot is a unit of length”
Page 31
Properties of a Unit
Symbol “ft”
Dimension “Foot is a unit of length”
Equivalence 1ft = 0.348m
Page 32
// Unit
public class Unit : NSObject, NSCopying {
public let symbol : String
public init(symbol: String)
}
NEW
Page 34
Dimension
Categories of units
Page 35
Dimension
Categories of unitsExpressed with different units• Length: km, m, ft, mi, etc.
Page 36
Dimension
Categories of unitsExpressed with different units• Length: km, m, ft, mi, etc.
Always has a base unitlet meter = UnitLength.baseUnit
Page 37
Dimension
Categories of unitsExpressed with different units• Length: km, m, ft, mi, etc.
Always has a base unitlet meter = UnitLength.baseUnit
Can perform conversions• km ⇆ ft, m ⇆ mi
Page 38
// Dimension
public class Dimension : Unit, NSCoding {
NEW
Page 39
// Dimension
public class Dimension : Unit, NSCoding {
public var converter : UnitConverter { get }
NEW
Page 40
// Dimension
public class Dimension : Unit, NSCoding {
public var converter : UnitConverter { get }
public init(symbol: String, converter: UnitConverter)
NEW
Page 41
// Dimension
public class Dimension : Unit, NSCoding {
public var converter : UnitConverter { get }
public init(symbol: String, converter: UnitConverter)
public class var baseUnit : Dimension
NEW
}
Page 42
Abstract unitsDimension
Instances as units
Page 43
Abstract unitsDimension
Instances as unitsSingletons for most common units
Page 44
Abstract unitsDimension
Instances as unitsSingletons for most common unitsInternational System of Units
Page 45
public class UnitLength : Dimension { /* Base unit - meters */ public class var kilometers: UnitLength { get } public class var meters: UnitLength { get } public class var feet: UnitLength { get } public class var miles: UnitLength { get }
... }
Abstract unitsDimension
Instances as unitsSingletons for most common unitsInternational System of Units
Page 46
Provided subclassesDimension
UnitAcceleration UnitElectricCurrent UnitIlluminance
UnitAngle UnitElectricPotentialDifference UnitMass
UnitArea UnitElectricResistance UnitPower
UnitConcentrationMass UnitEnergy UnitPressure
UnitDispersion UnitFrequency UnitSpeed
UnitDuration UnitFuelEfficiency UnitTemperature
UnitElectricCharge UnitLength UnitVolume
NEW
Page 47
// Implicit Conversion
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
let totalDistance = distanceTraveled + distanceToGo
value: 11, unit: .feet
Page 48
// Implicit Conversion
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
// let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
// let totalDistance = distanceTraveled + distanceToGo
Page 49
// Implicit Conversion
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
// let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
// let totalDistance = distanceTraveled + distanceToGo
let distanceToGo = Measurement(value: 6, unit: UnitLength.kilometers)
Page 50
// Implicit Conversion
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
// let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
// let totalDistance = distanceTraveled + distanceToGo
let distanceToGo = Measurement(value: 6, unit: UnitLength.kilometers)
let totalDistance = distanceTraveled + distanceToGo
Page 51
// Implicit Conversion
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
// let distanceToGo = Measurement(value: 6, unit: UnitLength.feet)
// let totalDistance = distanceTraveled + distanceToGo
let distanceToGo = Measurement(value: 6, unit: UnitLength.kilometers)
let totalDistance = distanceTraveled + distanceToGo
value: 6001.524, unit: .meters
Page 52
// Comparison Operators
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 6, unit: UnitLength.kilometers)
var distanceMarker : String
if (distanceTraveled > distanceToGo) {
distanceMarker = "Almost there!"
} else if (distanceTraveled < distanceToGo) {
distanceMarker = "Barely started!"
} else {
distanceMarker = "Halfway!"
}
Page 53
// Comparison Operators
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 6, unit: UnitLength.kilometers)
var distanceMarker : String
if (distanceTraveled > distanceToGo) {
distanceMarker = "Almost there!"
} else if (distanceTraveled < distanceToGo) {
distanceMarker = "Barely started!"
} else {
distanceMarker = "Halfway!"
}
Page 54
// Comparison Operators
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 5, unit: UnitLength.kilometers)
var distanceMarker : String
if (distanceTraveled > distanceToGo) {
distanceMarker = "Almost there!"
} else if (distanceTraveled < distanceToGo) {
distanceMarker = "Barely started!"
} else {
distanceMarker = "Halfway!"
}
print(distanceMarker)
Page 55
// Comparison Operators
let distanceTraveled = Measurement(value: 5, unit: UnitLength.feet)
let distanceToGo = Measurement(value: 5, unit: UnitLength.kilometers)
var distanceMarker : String
if (distanceTraveled > distanceToGo) {
distanceMarker = "Almost there!"
} else if (distanceTraveled < distanceToGo) {
distanceMarker = "Barely started!"
} else {
distanceMarker = "Halfway!"
}
print(distanceMarker)
“Barely started!”
Page 57
Unit Definition
In terms of base unit
Page 58
Unit Definition
In terms of base unitMethods to define conversion
Page 59
Unit Definition
In terms of base unitMethods to define conversionConvert within dimension
Page 61
Creating Units
Only define custom unitsConversion handled implicitly
Page 62
// Create Custom Units on the Fly
let jamz = UnitDuration(symbol: “jamz", converter: UnitConverterLinear(coefficient: 30))
Page 63
// Create Custom Units on the Fly
let jamz = UnitDuration(symbol: “jamz", converter: UnitConverterLinear(coefficient: 30))
Page 65
Conversion
baseUnit unit
NEW
Page 66
Conversion
baseUnit unitUnitConverter• baseUnitValue(fromValue value:)• value(fromBaseUnitValue baseUnitValue:)
NEW
Page 67
Conversion
baseUnit unitUnitConverter• baseUnitValue(fromValue value:)• value(fromBaseUnitValue baseUnitValue:)
UnitConverterLinear• baseUnitValue = value * coefficient + constant• value = (baseUnitValue - constant)/coefficient
NEW
Page 68
// “Jammin’ in the Streetz” Game - Custom Units
let jamz = UnitDuration(symbol: “jamz", converter: UnitConverterLinear(coefficient: 30))
Page 69
// “Jammin’ in the Streetz” Game - Custom Units
let jamz = UnitDuration(symbol: “jamz", converter: UnitConverterLinear(coefficient: 30))
baseUnitValue = 30 * jamzValue
jamzValue = baseUnitValue/30
Page 70
// “Jammin’ in the Streetz” Game - Custom Units
let jamz = UnitDuration(symbol: “jamz", converter: UnitConverterLinear(coefficient: 30))
let hopz = UnitLength(symbol: “hopz", converter: UnitConverterLinear(coefficient: 0.75))
Page 71
// “Jammin’ in the Streetz” Game - Custom Units
let jamz = UnitDuration(symbol: “jamz", converter: UnitConverterLinear(coefficient: 30))
let hopz = UnitLength(symbol: “hopz", converter: UnitConverterLinear(coefficient: 0.75))
baseUnitValue = 0.75 * hopzValue
hopzValue = baseUnitValue/0.75
Page 72
// “Jammin’ in the Streetz” Game - Custom Units
let jamz = UnitDuration(symbol: “jamz", converter: UnitConverterLinear(coefficient: 30))
let hopz = UnitLength(symbol: “hopz", converter: UnitConverterLinear(coefficient: 0.75))
let glidez = UnitLength(symbol: “glidez", converter: UnitConverterLinear(coefficient: 1.5))
Page 73
// “Jammin’ in the Streetz” Game - Custom Units
let jamz = UnitDuration(symbol: “jamz", converter: UnitConverterLinear(coefficient: 30))
let hopz = UnitLength(symbol: “hopz", converter: UnitConverterLinear(coefficient: 0.75))
let glidez = UnitLength(symbol: “glidez", converter: UnitConverterLinear(coefficient: 1.5))
baseUnitValue = 1.5 * glidezValue
glidezValue = baseUnitValue/1.5
Page 74
// “Jammin’ in the Streetz” Game - Custom Dimension
public class UnitDanceMove : Dimension {
Page 75
// “Jammin’ in the Streetz” Game - Custom Dimension
public class UnitDanceMove : Dimension {
static let wackyArmMovements = UnitDanceMove(symbol: "💪",
converter: UnitConverterLinear(coefficient: 1))
Page 76
// “Jammin’ in the Streetz” Game - Custom Dimension
public class UnitDanceMove : Dimension {
static let wackyArmMovements = UnitDanceMove(symbol: "💪",
converter: UnitConverterLinear(coefficient: 1))
1 💪 = 1 💪
Page 77
// “Jammin’ in the Streetz” Game - Custom Dimension
public class UnitDanceMove : Dimension {
static let wackyArmMovements = UnitDanceMove(symbol: "💪",
converter: UnitConverterLinear(coefficient: 1))
static let robot = UnitDanceMove(symbol: "🤖",
converter: UnitConverterLinear(coefficient: 4))
Page 78
// “Jammin’ in the Streetz” Game - Custom Dimension
public class UnitDanceMove : Dimension {
static let wackyArmMovements = UnitDanceMove(symbol: "💪",
converter: UnitConverterLinear(coefficient: 1))
static let robot = UnitDanceMove(symbol: "🤖",
converter: UnitConverterLinear(coefficient: 4))
1 🤖 = 4 💪
Page 79
// “Jammin’ in the Streetz” Game - Custom Dimension
public class UnitDanceMove : Dimension {
static let wackyArmMovements = UnitDanceMove(symbol: "💪",
converter: UnitConverterLinear(coefficient: 1))
static let robot = UnitDanceMove(symbol: "🤖",
converter: UnitConverterLinear(coefficient: 4))
static let cabbagePatch = UnitDanceMove(symbol: "👼",
converter: UnitConverterLinear(coefficient: 3))
Page 80
// “Jammin’ in the Streetz” Game - Custom Dimension
public class UnitDanceMove : Dimension {
static let wackyArmMovements = UnitDanceMove(symbol: "💪",
converter: UnitConverterLinear(coefficient: 1))
static let robot = UnitDanceMove(symbol: "🤖",
converter: UnitConverterLinear(coefficient: 4))
static let cabbagePatch = UnitDanceMove(symbol: "👼",
converter: UnitConverterLinear(coefficient: 3))
1 👼 = 3 💪
Page 81
// “Jammin’ in the Streetz” Game - Custom Dimension
public class UnitDanceMove : Dimension {
static let wackyArmMovements = UnitDanceMove(symbol: "💪",
converter: UnitConverterLinear(coefficient: 1))
static let robot = UnitDanceMove(symbol: "🤖",
converter: UnitConverterLinear(coefficient: 4))
static let cabbagePatch = UnitDanceMove(symbol: "👼",
converter: UnitConverterLinear(coefficient: 3))
static let jazzHands = UnitDanceMove(symbol: "👐",
converter: UnitConverterLinear(coefficient: 2))
}
Page 82
// “Jammin’ in the Streetz” Game - Custom Dimension
public class UnitDanceMove : Dimension {
static let wackyArmMovements = UnitDanceMove(symbol: "💪",
converter: UnitConverterLinear(coefficient: 1))
static let robot = UnitDanceMove(symbol: "🤖",
converter: UnitConverterLinear(coefficient: 4))
static let cabbagePatch = UnitDanceMove(symbol: "👼",
converter: UnitConverterLinear(coefficient: 3))
static let jazzHands = UnitDanceMove(symbol: "👐",
converter: UnitConverterLinear(coefficient: 2))
}1 👐 = 2 💪
Page 83
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
Page 84
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
public var stepsTaken : Measurement<UnitLength>
Page 85
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
public var stepsTaken : Measurement<UnitLength> .hopz
Page 86
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
public var stepsTaken : Measurement<UnitLength>
public var jamTime : Measurement<UnitDuration>
Page 87
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
public var stepsTaken : Measurement<UnitLength>
public var jamTime : Measurement<UnitDuration> .jamz
Page 88
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
public var stepsTaken : Measurement<UnitLength>
public var jamTime : Measurement<UnitDuration>
public var danceMoves : Measurement<UnitDanceMove>
Page 89
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
public var stepsTaken : Measurement<UnitLength>
public var jamTime : Measurement<UnitDuration>
public var danceMoves : Measurement<UnitDanceMove> .robot
Page 90
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
public var stepsTaken : Measurement<UnitLength>
public var jamTime : Measurement<UnitDuration>
public var danceMoves : Measurement<UnitDanceMove>
public var danceRate : Measurement<UnitSpeed> {
Page 91
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
public var stepsTaken : Measurement<UnitLength>
public var jamTime : Measurement<UnitDuration>
public var danceMoves : Measurement<UnitDanceMove>
public var danceRate : Measurement<UnitSpeed> { .metersPerSecond
Page 92
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
public var stepsTaken : Measurement<UnitLength>
public var jamTime : Measurement<UnitDuration>
public var danceMoves : Measurement<UnitDanceMove>
public var danceRate : Measurement<UnitSpeed> {
let stepsInMeters = stepsTaken.converted(to: .meters)
Page 93
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
public var stepsTaken : Measurement<UnitLength>
public var jamTime : Measurement<UnitDuration>
public var danceMoves : Measurement<UnitDanceMove>
public var danceRate : Measurement<UnitSpeed> {
let stepsInMeters = stepsTaken.converted(to: .meters)
let jamTimeInSeconds = jamTime.converted(to: .seconds)
Page 94
// “Jammin’ in the Streetz” Game - Jam Session
public struct JamSession {
public var stepsTaken : Measurement<UnitLength>
public var jamTime : Measurement<UnitDuration>
public var danceMoves : Measurement<UnitDanceMove>
public var danceRate : Measurement<UnitSpeed> {
let stepsInMeters = stepsTaken.converted(to: .meters)
let jamTimeInSeconds = jamTime.converted(to: .seconds)
return Measurement(value: (stepsInMeters.value / jamTimeInSeconds.value),
unit: .metersPerSecond)
}
}
Page 95
Formatting Measurements
Page 97
Formatting Is Hard
Country Expected String
Page 98
Formatting Is Hard
Country Expected String
Canada “5 km”
Page 99
Formatting Is Hard
Country Expected String
Canada “5 km”
China “5 “
Page 100
Formatting Is Hard
Country Expected String
Canada “5 km”
China “5 “
Egypt “٥ كم“
Page 101
Formatting Is Hard
Country Expected String
Canada “5 km”
China “5 “
Egypt “٥ كم“
United States “3.1 mi”
Page 102
Let Us Do the Work
Page 103
Let Us Do the Work
New formatter
Page 104
Let Us Do the Work
New formatterMeasurements and units
Page 105
Let Us Do the Work
New formatterMeasurements and unitsLocale-aware formatting
Page 106
// MeasurementFormatter
public class MeasurementFormatter : Formatter, NSSecureCoding {
NEW
Page 107
// MeasurementFormatter
public class MeasurementFormatter : Formatter, NSSecureCoding {
public var unitOptions: MeasurementFormatter.UnitOptions
NEW
Page 108
// MeasurementFormatter
public class MeasurementFormatter : Formatter, NSSecureCoding {
public var unitOptions: MeasurementFormatter.UnitOptions
public var unitStyle: Formatter.UnitStyle
NEW
Page 109
// MeasurementFormatter
public class MeasurementFormatter : Formatter, NSSecureCoding {
public var unitOptions: MeasurementFormatter.UnitOptions
public var unitStyle: Formatter.UnitStyle
@NSCopying public var locale: Locale!
NEW
Page 110
// MeasurementFormatter
public class MeasurementFormatter : Formatter, NSSecureCoding {
public var unitOptions: MeasurementFormatter.UnitOptions
public var unitStyle: Formatter.UnitStyle
@NSCopying public var locale: Locale!
@NSCopying public var numberFormatter: NumberFormatter!
NEW
Page 111
// MeasurementFormatter
public class MeasurementFormatter : Formatter, NSSecureCoding {
public var unitOptions: MeasurementFormatter.UnitOptions
public var unitStyle: Formatter.UnitStyle
@NSCopying public var locale: Locale!
@NSCopying public var numberFormatter: NumberFormatter!
public func string(from measurement: Measurement<Unit>) -> String
NEW
Page 112
// MeasurementFormatter
public class MeasurementFormatter : Formatter, NSSecureCoding {
public var unitOptions: MeasurementFormatter.UnitOptions
public var unitStyle: Formatter.UnitStyle
@NSCopying public var locale: Locale!
@NSCopying public var numberFormatter: NumberFormatter!
public func string(from measurement: Measurement<Unit>) -> String
public func string(from unit: Unit) -> String
NEW
}
Page 114
Unit Options
Formats preferred unit of locale by defaultTakes purpose into account
Page 115
Unit Options
UnitOptions Measurement Locale Example String
Page 116
Unit Options
UnitOptions Measurement Locale Example String
.providedUnit value: 5, unit: .kilometers “en_US” “5 km”
Page 117
Unit Options
UnitOptions Measurement Locale Example String
.providedUnit value: 5, unit: .kilometers “en_US” “5 km”
.naturalScale value: 1000, unit: .meters “fr_FR” “1 km”
Page 118
Unit Options
UnitOptions Measurement Locale Example String
.providedUnit value: 5, unit: .kilometers “en_US” “5 km”
.naturalScale value: 1000, unit: .meters “fr_FR” “1 km”
.temperatureWithoutUnit value: 90, unit: .fahrenheit “en_US” “90°“
Page 119
// “Jammin’ in the Streetz” Game - Formatting Units
let formatter = MeasurementFormatter()
Page 120
// “Jammin’ in the Streetz” Game - Formatting Units
let formatter = MeasurementFormatter()
let distance = Measurement(value: 5, unit: UnitLength.kilometers)
Page 121
// “Jammin’ in the Streetz” Game - Formatting Units
let formatter = MeasurementFormatter()
let distance = Measurement(value: 5, unit: UnitLength.kilometers)
let result = formatter.string(from: distance)
Page 122
// “Jammin’ in the Streetz” Game - Formatting Units
let formatter = MeasurementFormatter()
let distance = Measurement(value: 5, unit: UnitLength.kilometers)
let result = formatter.string(from: distance)
“3.1 mi”
Page 123
// “Jammin’ in the Streetz” Game - Formatting Custom Units
let formatter = MeasurementFormatter()
let distance = Measurement(value: 5, unit: UnitLength.kilometers)
let result = formatter.string(from: distance)
let hopz = UnitLength(symbol: “hopz", converter: UnitConverterLinear(coefficient: 0.75))
Page 124
// “Jammin’ in the Streetz” Game - Formatting Custom Units
let formatter = MeasurementFormatter()
let distance = Measurement(value: 5, unit: UnitLength.kilometers)
let result = formatter.string(from: distance)
let hopz = UnitLength(symbol: “hopz", converter: UnitConverterLinear(coefficient: 0.75))
let hopzDistance = Measurement(value: 1000, unit: hopz)
Page 125
// “Jammin’ in the Streetz” Game - Formatting Custom Units
let formatter = MeasurementFormatter()
let distance = Measurement(value: 5, unit: UnitLength.kilometers)
let result = formatter.string(from: distance)
let hopz = UnitLength(symbol: “hopz", converter: UnitConverterLinear(coefficient: 0.75))
let hopzDistance = Measurement(value: 1000, unit: hopz)
let resultingHopz = formatter.string(from: hopzDistance)
Page 126
// “Jammin’ in the Streetz” Game - Formatting Custom Units
let formatter = MeasurementFormatter()
let distance = Measurement(value: 5, unit: UnitLength.kilometers)
let result = formatter.string(from: distance)
let hopz = UnitLength(symbol: “hopz", converter: UnitConverterLinear(coefficient: 0.75))
let hopzDistance = Measurement(value: 1000, unit: hopz)
let resultingHopz = formatter.string(from: hopzDistance)
“0.466 mi”
Page 127
// “Jammin’ in the Streetz” Game - Formatting Provided Unit
formatter.unitOptions = [.providedUnit]
Page 128
// “Jammin’ in the Streetz” Game - Formatting Provided Unit
formatter.unitOptions = [.providedUnit]
let hopzDistance = Measurement(value: 1000, unit: hopz)
Page 129
// “Jammin’ in the Streetz” Game - Formatting Provided Unit
formatter.unitOptions = [.providedUnit]
let hopzDistance = Measurement(value: 1000, unit: hopz)
let resultingHopz = formatter.string(from: hopzDistance)
Page 130
// “Jammin’ in the Streetz” Game - Formatting Provided Unit
formatter.unitOptions = [.providedUnit]
let hopzDistance = Measurement(value: 1000, unit: hopz)
let resultingHopz = formatter.string(from: hopzDistance)
“1000 hopz”
Page 131
// “Jammin’ in the Streetz” Game - Formatting Provided Unit
formatter.unitOptions = [.providedUnit]
let hopzDistance = Measurement(value: 1000, unit: hopz)
let resultingHopz = formatter.string(from: hopzDistance)
let robotDance = Measurement(value: 30, unit: UnitDanceMove.robot)
Page 132
// “Jammin’ in the Streetz” Game - Formatting Provided Unit
formatter.unitOptions = [.providedUnit]
let hopzDistance = Measurement(value: 1000, unit: hopz)
let resultingHopz = formatter.string(from: hopzDistance)
let robotDance = Measurement(value: 30, unit: UnitDanceMove.robot)
let resultingRobotDances = formatter.string(from: robotDance)
Page 133
// “Jammin’ in the Streetz” Game - Formatting Provided Unit
formatter.unitOptions = [.providedUnit]
let hopzDistance = Measurement(value: 1000, unit: hopz)
let resultingHopz = formatter.string(from: hopzDistance)
let robotDance = Measurement(value: 30, unit: UnitDanceMove.robot)
let resultingRobotDances = formatter.string(from: robotDance)
“30 🤖”
Page 134
DemoDisplaying locale-aware measurements in your app
Peter Hosey Software Engineer, Foundation
Page 136
Summary
New model objects
Page 137
Summary
New model objectsMeasurementFormatter for formatting
Page 138
Summary
New model objectsMeasurementFormatter for formattingPowerful localization for free
Page 139
More Information
https://developer.apple.com/wwdc16/238
Page 140
Related Sessions
Internationalization Best Practices Mission Tuesday 9:00AM
What’s New in Cocoa Nob Hill Tuesday 11:00AM
What’s New in Foundation for Swift Mission Tuesday 4:00PM