NS测量


快速说明-我将来所有的帖子都将发布在我的专用网站上,并且此出版物不再更新。 谢谢阅读!


对于软件工程师来说,度量单位,事物或项目并不总是最迷人的工作。 尽管不像编写高效的用户界面库那样令人振奋,也不如使网络代码轻松编织并发执行那样让人感到满足,但iOS中的度量单位仍然经常做错事。

一个人怎么能以一种国际化的方式而不是一个仓促的方式编写这样的代码? 基金会(通常如此)拥有答案。 从iOS 10开始

本周,我们来看一下NSMeasurement和朋友。

比你想像的更普遍

软件总是会出现一些情况,这些情况向用户展示了一些可测量或可量化的东西。 而且,当该软件(iOS)在全球数十亿设备上运行时,代表这些事物的国际化价值的需求不仅变得越来越重要,而且也变得至关重要。

正确地获得这样的度量和单位并不是基线经验,您应该只对软件有期望。

因此,这些API不仅有助于明显的“转换器”应用程序,而且还可以帮助游戏,购物清单以及介于两者之间的所有其他内容:

  • 您代表时间的量度?️吗?
  • 行驶了一段距离?
  • 我们旅行的速度🗺?
  • 物体的重量⚖️?

因此,在表面上使用简单的double类型的诱惑很有意义,并且在其他任何地方都可以打破:

  //从技术上讲,我们甚至为失败设置变量名 
让里程旅行:双

NSMeasurement及其所有部门

在前面的示例之后,我们真正需要的是一个精确的,真实的结构来表示测量结果。 虽然里程数当然是一种度量,但在Murica的context语境中,通常仅是有意义的度量。 因此,基金会对测量的支持实际上是通用的:

 公共结构Measurement  

请注意,出于文体目的,并且由于我每天在Objective-C中进行编码,因此在本文中,我将使用带有NS前缀的框架进行引用。 所有这些对象都作为值类型和结构正确地桥接到Swift。

它提供了一种提供通用度量单位以及与之对应的值的方法。 它的初始值设定项将要求两个:

 公共初始化(值:Double,单位:UnitType) 

每个单位都将始终具有符号,尽管并非每个单位都具有尺寸,也不总是彼此等效。 当然,需要注意一点,但是最有可能使用尺寸单位。 但是,由于这个原因,NSUnit的指定初始化程序仅需要一个符号:

 公共类单位:NSObject,NSCopying 
{
公共让符号:字符串
公共初始化(符号:字符串)
}

对于NSMeasurement,此单位类型负责大部分工作,您可以通过其初始化程序定义要使用的单位,但更常见的是,您将使用Apple提供给我们的NSDimension(其子类为NSUnit)。 然后,每个尺寸单位将进一步降低到该单位内存在的给定尺寸。

例如,假设我们要测量时间。 我们的单位是持续时间,但是我们有几种表示持续时间的方法,例如秒,分钟和小时:

 让abstractValue = 1.0 // 1秒 
让秒=度量值(值:abstractValue,单位:UnitDuration.seconds)
// 1分钟
let minutes =度量值(值:abstractValue,单位:UnitDuration.minutes)
// 1小时
let hours =度量值(值:abstractValue,单位:UnitDuration.hours)

基础包括卡车的尺寸单位,从电流到压力都应包括在内。 实际上,尽管您可以自由继承并创建自己的单元,但是对此有相当强大的支持,但我不确定您是否需要。

以下是一些免费烘烤的常见尺寸单位:

  • UnitLength:基本单位是米(m)
  • 单位质量:基本单位为千克(kg)
  • UnitDuration:基本单位是秒(秒)
  • 单位面积:基本单位为平方米(m²)
  • UnitAcceleration:基本单位是米/秒平方(m /s²)

大约有170个维度单位类型,Foundation可能已经想到了您的用例。

进行测量

由于测量符合开箱即用的事实,因此进行测量是微不足道的,因此比较是统一进行的:

 让abstractValue = 1.0let秒=度量值(值:abstractValue,单位:UnitDuration.seconds) 
let minutes =度量值(值:abstractValue,单位:UnitDuration.minutes)
// 61.0秒,以尺寸的基本单位为单位
让totalTime =秒+分钟
// 30.5秒
让halfTheTime = totalTime / 2

整个测量API会为您完成所有繁重的工作。 当您使用相同尺寸但形式不同的单元进行操作时,这是正确的。 操作结果将仅提供基本单位类型:

  let imperialLength =测量(值:5280.0,单位:UnitLength.feet)let metricLength =测量(值:0.62,单位:UnitLength。公里)// 2229.344米 
让totalLength = imperialLength + metricLength

扩展实用性的是NSUnitConverter,它是一个抽象类,用于将单位与给定尺寸的基本单位相互转换。 在大多数情况下,这将是遵守线性方程式或比例因子的单位。 因此,将提供UnitConverterLinear:

  let imperialLength =测量(值:5280.0,单位:UnitLength.feet)let metricLength =测量(值:0.62,单位:UnitLength。公里)// 2229.344米 
让totalLength = imperialLength + metricLength
// 1.385英里
让justMiles = totalLength.converted(到:UnitLength.miles)

不必担心创建彼此不相关的转化。 由于每种类型的转换都需要其通用单位类型,因此会产生构建时间错误:

  //构建错误 
让废话= totalLength.converted(到:UnitTemperature.celsius)

如果您冒险使用NSNumberFormatter,那么在用户界面中显示这些值将是非常熟悉的。 它的近亲NSMeasurementFormatter的使用在本质上是相同的。

这是非常理想的,因为在我们自己的时间编写这些类型的字符串很快会变得很麻烦。

 如果(是加拿大) 
{
//公里👌
}
否则(中文)
{
//翻译单位😐
}
否则(isArabic)
{
//翻译单位,数字表示并从右到左😱
}

当然,基金会和朋友对此表示赞同:

 让距离=测量(值:10,单位:UnitLength.miles)let frenchDistance = MeasurementFormatter() 
frenchDistance.locale =语言环境(标识符:“ fr”)
让chineseDistance = MeasurementFormatter()
chineseDistance.locale =语言环境(标识符:“ zh”)
让arabicDistance = MeasurementFormatter()
arabicDistance.locale =语言环境(标识符:“ ar”)
//🇫🇷 -> 16,093公里
print(“🇫🇷-> \(frenchDistance.string(from:distance))”)
//🇨🇳 -> 16.093公里
print(“🇨🇳-> \(chineseDistance.string(from:distance))”)
//🇯🇴 -> ١٦。٠٩٣كمprint(“🇯🇴-> \(arabicDistance.string(from:distance))”)

由于度量与数字紧密相关,因此也可以将度量格式器与数字格式器配对以指定数字,例如:

 设让距离=测量值(值:0.2,单位:UnitLength.miles)let frenchDistance = MeasurementFormatter() 
frenchDistance.locale =语言环境(标识符:“ fr”)
//🇫🇷 -> 0,322公里
print(“🇫🇷-> \(frenchDistance.string(from:distance))”)
让digitFormat = NumberFormatter()
digitFormat.minimumSignificantDigits = 4
frenchDistance.numberFormatter = digitFormat //🇫🇷 -> 0.321868公里
print(“🇫🇷-> \(frenchDistance.string(from:distance))”)

测量格式化程序可以为您提供几种配置。 请务必浏览其文档。 还要注意,格式化程序在初始化时将采用其默认的系统语言环境,因此通常无需像我们在此处所做的那样直接将其分配给其语言环境属性。

测试语言环境-.easy方法

快速的脚注。 利用Foundation的度量和单位API的部分神奇之处在于它们了解区域设置。 如果您当前正在更改iOS模拟器中的位置以查看情况如何发生变化,则可能会采用另一种方法。

只需复制您的方案,然后选择所需的语言环境即可:

  • 编辑方案
  • 点击“重复计划”,它在Xcode 9的左下方
  • 命名
  • 在运行->选项->应用程序区域下,然后选择要测试的区域

很好,因为这是没有大惊小怪和刻意的方法。 它不需要更改代码,也不需要(总是可靠的🤞)iOS模拟器。

此外,通过以与编辑区域相同的方式编辑“应用程序语言”,您可以使用相同的方法来测试界面中的字符串本地化。

包起来

直到我开始为一个国际团队工作时,我才真正开始欣赏iOS内的精确测量。 或者-甚至是正确的测量周期单位。

虽然世界其他地区都采用公制,但在这里,我像拇指一样酸痛地伸出来,同时通过英制传达距离。 Siri有灵魂,我知道这一点,因为她讨厌回答等于1公里的英里数。 当她第144次为我回答时,我以她冷淡,坚硬,数字的声音听到了hear。

我们都希望不要成为在我们自己的软件中提供错误单位或错误测量结果的应用程序。 基金会已经覆盖了我们。

直到下次time️


乔丹·摩根(@ JordanMorgan10)| 推特

Jordan Morgan(@ JordanMorgan10)的最新推文。 iOS位于@buffer。 在自己的时间上处理支出堆栈…

www.twitter.com

 如果您喜欢本周的帖子,请随时继续并进行NSRecommend(this,where:below);