Программирование
Введение в Measurement в Swift
Если вам доведется работать с единицами измерения и преобразованиями, попробуйте Measurement. Он сам справится с локализацией, конвертацией и форматированием.
Недавно я работал с единицами и преобразованиями единиц измерения в Swift. Через некоторое время я вспомнил, что в Swift есть встроенная структура для этого: Measurement
. Эта статья — введение в возможности и использование Measurement
.
Чтобы использовать Measurement
, вы инициализируете его значением и типом единицы измерения. Значение должно быть Double
, а тип единицы определяет тип измерения и масштаб единиц. Вот пример задания длины в сантиметрах:
let length = 1234.56 let lengthMeasurement = Measurement(value: length, unit: UnitLength.centimeters)
Существует множество поддерживаемых типов единиц. Все они начинаются с Unit, так что начните вводить и посмотрите, что получится. После того как вы определите тип юнита, введите точку, и кодовое завершение предложит все возможные юниты этого типа. Их огромное множество, включая самые непонятные:
Я запускаю это в 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
может выполнять преобразования, например, так:
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
. Он сам справится с локализацией, конвертацией и форматированием.
-
Новости4 недели назад
Видео и подкасты о мобильной разработке 2025.16
-
Новости3 недели назад
Видео и подкасты о мобильной разработке 2025.17
-
Разработка4 недели назад
Расширенные архитектурные правила в SwiftLint: часть 1
-
Видео и подкасты для разработчиков4 недели назад
Не два байта переслать: эмуляция бесконтактных карт на мобильных устройствах