title: How to determine the display count of a Swift String?
body: <p>I've reviewed questions such as <a href="https://stackoverflow.com/questions/24037711/get-the-length-of-a-string">Get the length of a String</a> and <a href="https://stackoverflow.com/questions/43618487/why-are-emoji-characters-like-treated-so-strangely-in-swift-strings">Why are emoji characters like &#128105;‍&#128105;‍&#128103;‍&#128102; treated so strangely in Swift strings?</a> but neither cover this specific question.</p>
  
  <p>This all started when trying to apply skin tone modifiers to Emoji characters (see <a href="https://stackoverflow.com/questions/56674968/add-skin-tone-modifier-to-an-emoji-programmatically">Add skin tone modifier to an emoji programmatically</a>). This led to wondering what happens when you apply a skin tone modifier to a regular character such as <code>"A"</code>.</p>
  
  <p>Examples:</p>
  
  <pre><code>let tonedThumbsUp = "" + "" // 
  let tonedA = "A" + "" // A
  </code></pre>
  
  <p>I'm trying to detect that second case. The <code>count</code> of both of those strings is 1. And the <code>unicodeScalars.count</code> is 2 for both.</p>
  
  <p>How do I determine if the resulting string appears as a single character when displayed? In other words, how can I determine if the skin tone modifier was applied to make a single character or not?</p>
  
  <p>I've tried a few ways to dump information about the string but none give the desired result.</p>
  
  <pre><code>func dumpString(_ str: String) {
      print("Raw:", str, str.count)
      print("Scalars:", str.unicodeScalars, str.unicodeScalars.count)
      print("UTF16:", str.utf16, str.utf16.count)
      print("UTF8:", str.utf8, str.utf16.count)
      print("Range:", str.startIndex, str.endIndex)
      print("First/Last:", str.first == str.last, str.first, str.last)
  }
  
  dumpString("A")
  dumpString("\u{1f469}\u{1f3fe}")
  </code></pre>
  
  <p>Results:</p>
  
  <pre>
  Raw: A 1
  Scalars: A 2
  UTF16: A 3
  UTF8: A 3
  First/Last: true Optional("A") Optional("A")
  Raw:  1
  Scalars:  2
  UTF16:  4
  UTF8:  4
  First/Last: true Optional("") Optional("")
  </pre>