title: NSAttributedString and emojis: issue with positions and lengths
body: <p>I'm coloring some parts of a text coming from an API (think "@mention" as on Twitter) using NSAttributedString.</p>
  
  <p>The API gives me the text and an array of entities representing the parts of the text that are mentions (or links, tags, etc) which should be colored.</p>
  
  <p>But sometimes, the coloration is offset because of emojis.</p>
  
  <hr>
  
  <p>For example, with this text:</p>
  
  <blockquote>
    <p>"@ericd Some text. @apero"</p>
  </blockquote>
  
  <p>the API gives:</p>
  
  <blockquote>
    <p>[
       {
          "text" : "ericd",
          "len" : 6,
          "pos" : 0
       },
       {
          "text" : "apero",
          "len" : 6,
          "pos" : 18
       }
    ]</p>
  </blockquote>
  
  <p>which I successfully translate to an NSAttributedString using NSRange:</p>
  
  <pre><code>for m in entities.mentions {
      let r = NSMakeRange(m.pos, m.len)
      myAttributedString.addAttribute(NSForegroundColorAttributeName, value: someValue, range: r)
  }
  </code></pre>
  
  <p>We see that <code>"pos": 18</code> is correct, this is where "@apero" starts. The colored parts are "@ericd" and "@apero", as expected.</p>
  
  <p><strong>but when some specific combinations of emojis are used in the text, the API does not translate well to NSATtributedString, the coloration is offset</strong>:</p>
  
  <blockquote>
    <p>"@ericd Some text. ✌ @apero"</p>
  </blockquote>
  
  <p>gives: </p>
  
  <blockquote>
    <p>[
       {
          "text" : "ericd",
          "len" : 6,
          "pos" : 0
       },
       {
          "text" : "apero",
          "len" : 6,
          "pos" : 22
       }
    ]</p>
  </blockquote>
  
  <p><code>"pos": 22</code>: the API author states that this is correct, and I understand their point of view. </p>
  
  <p><strong>Unfortunately, NSAttributedString does not agree, my coloration is off:</strong></p>
  
  <p><a href="https://i.stack.imgur.com/G3Wdc.png" rel="noreferrer"><img src="https://i.stack.imgur.com/G3Wdc.png" alt="enter image description here"></a></p>
  
  <p>The last characters for the second mention are not colored (because the "pos" is too short because of the emojis?).</p>
  
  <p>As you might have already guessed, I cannot in any way change the way the API behaves, I have to adapt on client side.</p>
  
  <p>Except that... I have no idea what to do. Should I try to detect what kind of emojis are in the text and manually amend the position of mentions when there's a problematic emoji? But what would be the criteria to detect which emoji shifts the position and which doesn't? And how to decide how much offset I need? Maybe the problem is caused by NSAttributedString?</p>
  
  <p>I understand that this is related to the emojis length once composed compared to their length as discrete characters, but... well... I'm lost (sigh).</p>
  
  <hr>
  
  <p>Note that I've tried to implement a solution similar to <a href="https://github.com/berg/ANAPIRangeAdapter/blob/master/ANAPIRangeAdapter/NSString%2BANAPIRangeAdapter.m" rel="noreferrer">this stuff</a> because my API is compatible with this one, but it only worked partially, some emojis were still breaking the indexes:</p>
  
  <p><a href="https://i.stack.imgur.com/MxDgG.png" rel="noreferrer"><img src="https://i.stack.imgur.com/MxDgG.png" alt="enter image description here"></a></p>