Connect with us

Программирование

Введение в Measurement в Swift

Если вам доведется работать с единицами измерения и преобразованиями, попробуйте Measurement. Он сам справится с локализацией, конвертацией и форматированием.

Опубликовано

/

     
     

Недавно я работал с единицами и преобразованиями единиц измерения в Swift. Через некоторое время я вспомнил, что в Swift есть встроенная структура для этого: Measurement. Эта статья — введение в возможности и использование Measurement.

Чтобы использовать Measurement, вы инициализируете его значением и типом единицы измерения. Значение должно быть Double, а тип единицы определяет тип измерения и масштаб единиц. Вот пример задания длины в сантиметрах:

let length = 1234.56
let lengthMeasurement = Measurement(value: length, unit: UnitLength.centimeters)

Существует множество поддерживаемых типов единиц. Все они начинаются с Unit, так что начните вводить и посмотрите, что получится. После того как вы определите тип юнита, введите точку, и кодовое завершение предложит все возможные юниты этого типа. Их огромное множество, включая самые непонятные:

Введение в Measurement в Swift

Я запускаю это в Playground , и когда я вывожу lengthMeasurement, то получаю 1234.56 см, как и следовало ожидать.

Волшебство происходит, когда вы начинаете форматировать Measurement.

let formattedLength = lengthMeasurement.formatted()
print(formattedLength)

Запустив этот код, я получил 12 м, что является гораздо более читабельной версией.

Играя с большими и меньшими значениями, я добился, чтобы он показывал см, м или км. Он даже добавил разделитель тысяч, когда я перешел к очень большому числу. Странно, но я не смог заставить его использовать меньшую единицу измерения, чем та, с которой я начал. Даже при 0.00001 см он все равно не использовал мм, так что, думаю, урок заключается в том, что начинать нужно с самых маленьких единиц, которые вы хотите показать.

Теперь о самом интересном. Я зашел в Настройки системы -> Общие -> Язык и регион и изменил систему измерений с метрической на американскую. Запустив теперь Playground, мое первоначальное значение 1234.56 см дало отформатированное значение 41 фут! Большее значение дало мне mi (мили), а меньшее — in (дюймы). Таким образом, форматирование использует системные настройки для выбора единиц измерения. Нет необходимости преобразовывать измерения в соответствии с местностью пользователя — отформатированное значение Measurement сделает это за вас!

Преобразование

Но что, если вы хотите сделать конвертацию? Я люблю готовить, и большинство рецептов в Интернете предполагают, что все используют градусы Фаренгейта для своих духовок. Спасибо всем авторам рецептов, которые указывают и градусы Цельсия, это очень ценно.

Как вы можете себе представить, я провожу некоторое время на кухне, разговаривая со своим запястьем, чтобы мои Apple Watch и Siri могли делать преобразования за меня:

Введение в Measurement в Swift

На этом скриншоте результат моего запроса показывает и Фаренгейт, и Цельсий. Давайте попробуем сделать это сами.

Во-первых, Measurement может выполнять преобразования, например, так:

let fahrenheit = 400.0
let fahrenheitMeasurement = Measurement(
  value: fahrenheit,
  unit: UnitTemperature.fahrenheit
)
print(fahrenheitMeasurement)

let celsiusMeasurement = fahrenheitMeasurement.converted(to: .celsius)
print(celsiusMeasurement)

Это выводит 400.0 °F и 204.44444444444832 °C. Если вам нужен доступ к числовому результату преобразования, вы можете получить Double с помощью celsiusMeasurement.value.

Но, как и следовало ожидать, если вы используете форматирование, обе версии будут показаны в градусах Цельсия, потому что это моя системная настройка:

print("\(fahrenheitMeasurement.formatted()) = \(celsiusMeasurement.formatted())")

Код выводит 204.444444°C = 204.444444°C, что, хотя и является неоспоримым фактом, не очень полезно. И он показывает слишком много знаков после запятой — моя духовка не настолько точна!

Здесь мы можем использовать MeasurementFormatter, который позволяет нам указать несколько параметров:

let formatter = MeasurementFormatter()
formatter.unitOptions = .providedUnit
formatter.numberFormatter.maximumFractionDigits = 0
formatter.unitStyle = .medium

Я попробовал:

let formattedFahrenheit = formatter.string(from: fahrenheitMeasurement)
let formattedCelsius = formatter.string(from: celsiusMeasurement)

print("\(formattedFahrenheit) = \(formattedCelsius)")

И получил 400°F = 204°C, что даже более полезно для приготовления пищи, чем то, что показывали мои часы.

Ключевым моментом для отображения обеих температур является установка в UnitOptions значения providedUnit, которое заставляет использовать единицы измерения, указанные в Measurement. После этого numberFormatter — это стандартный NumberFormatter со всеми его опциями. unitStyle может быть коротким, средним или длинным. По умолчанию используется средний, но я указал его, чтобы иметь возможность экспериментировать с различными стилями.

Так что, если вам доведется работать с единицами измерения и преобразованиями, попробуйте Measurement. Он сам справится с локализацией, конвертацией и форматированием.

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: