在iOS上不一致地处理表情符号序列?

时间:2017-11-28 16:51:02

标签: ios swift macos unicode emoji

在iOS和macOS上,regional indicator symbols的序列呈现为国旗表情符号,如果序列无效,则会显示实际符号:

Plain regional indicator symbols.

但是,如果序列恰好包含一对未映射到标志表情符号的区域指示符号,则潜在的标志将在第一个匹配的基础上呈现:

Some funky rendering.

iOS / macOS渲染符号:F F I S E S。

在Swift 3中,连续的区域指标符号都被归为一个Character,这意味着一个Character对象可以包含理论上无限量的UnicodeScalar个对象,只要它们是所有区域指标符号。从本质上讲,Swift 3根本没有打破区域指标符号。

另一方面,在Swift 4中,一个Character对象在其Unicode标量表示中最多包含两个区域指示符号。另外,并且可以理解,不考虑序列的有效性,因此区域指示符号序列在每两个标量处被简单地分解并被认为是Character。现在,迭代上面的相同字符串并打印每个字符会产生以下结果:

Some other funky rendering.

包含符号的Swift 4字符串:F F I S E S。

这将我们带到实际的问题 - iOS和macOS如何呈现序列的问题,或者Swift 4如何构造字符串中的Character表示?

我很好奇哪一方最适合报告这种特性。

以下是Swift 4中行为的最小可重现代码段:

// Regional indicator symbols F F I S E S
var string = "\u{1f1eb}\u{1f1eb}\u{1f1ee}\u{1f1f8}\u{1f1ea}\u{1f1f8}"

for character in string {
    print(character)
}

1 个答案:

答案 0 :(得分:0)

经过一些调查后,似乎没有错,尽管Swift 4中实施的方法更符合推荐。

根据Unicode标准(强调我的):

  

单个区域指标符号的代表性字形只是一个包含大写拉丁字母的虚线框。 Unicode标准没有规定如何呈现区域指标符号对。但是,当前的行业惯例广泛地将成对的区域指标符号解释为表示与相应的ISO 3166地区代码相关联的标志。

     

- The Unicode Standard, Version 10.0 – Core Specification,第836页。

然后,在下一页:

  

符合Unicode标准不要求符合UTS#51。然而,UTS#51中规定的区域指示符符号对的解释和显示现在已被广泛部署,因此实际上不建议尝试将区域指示符符号对解释为表示除表情符号标志之外的任何其他符号。

     

- Unicode标准,10.0版 - 核心规范,第837页。

由此我得知,虽然标准没有为如何呈现标志设置任何规则,但是在iOS和macOS中处理无效标志序列的呈现的所选路径是不可取的。因此,即使序列中还存在有效标记,渲染器也应始终将两个连续的区域指示符符号视为标记。

最后,看看UTS#51,或"表情符号规范":

  

用于呈现系统没有特定标志或其他字形的emoji_flag_sequence的选项包括:

     
      
  • 将每个REGIONAL INDICATOR符号分别显示为虚线方框中的字母,如Unicode图表所示。这提供了有关所指定特定区域的信息,但对某些用户来说可能会有些不可思议。

  •   
  • 对于所有不受支持的REGIONAL INDICATOR对,显示相同的“缺失标志”字形,例如下面显示的图像。这表明支持的对旨在表示某个区域的标志,而不指示哪一个。

  •   
     
    

Missing flag glyph.

  
     

- Unicode Technical Standard #51, revision 12,附件B。

因此,总而言之,最佳做法是将无效标志序列表示为一对区域指示符号 - 与Swift 4字符串中Character个对象的情况完全相同 - 或者作为通用缺失标志字形。