Cadena de text con EMOJI causando problemas con NSRange

Estoy usando TTTAttributedLabel para aplicar formatting a text, pero parece fallar porque bash aplicar formatting a un range que incluye emoji. Ejemplo:

NSString *text = @"@user1234 🍺🍺 #hashtag"; // text.length reported as 22 by NSLog as each emoji is 2 chars in length cell.textLabel.text = text; int length = 8; int start = 13; NSRange *range = NSMakeRange(start, length); if (!NSEqualRanges(range, NSMakeRange(NSNotFound, 0))) { // apply formatting to TTTAttributedLabel [cell.textLabel addLinkToURL:[NSURL URLWithString:[NSString stringWithFormat:@"someaction://hashtag/%@", [cell.textLabel.text substringWithRange:range]]] withRange:range]; } 

Nota: Pasé los valores NSRange de una API, así como la cadena de text.

En lo anterior estoy intentando aplicar formatting a #hashtag. Normalmente esto funciona bien, pero debido a que tengo emoji involucrado en la cadena, creo que el range identificado está tratando de formatear el emoji, ya que en realidad son valores UTF, que en TTTAttributedLabel provoca un locking (en realidad se cuelga sin locking, pero …)

Curiosamente, funciona bien si hay 1 emoji, pero se rompe si hay 2.

¿Alguien puede ayudarme a descubrir qué hacer aquí?

Supongo que esto proviene de la API de Twitter, y está intentando utilizar el dictionary de entidades que devuelven. Acabo de escribir un código para admitir el event handling esos ranges junto con la versión de NSString del range de una cadena.

Mi enfoque fue "arreglar" el dictionary de entidades que Twitter regresa para hacer frente a los caracteres adicionales. No puedo compartir el código, por varios motivos, pero esto es lo que hice:

  1. Haga una copy profunda mutable del dictionary de entidades.
  2. unichar por todo el range de la secuencia, unichar por unichar , haciendo esto:
    1. Compruebe si el unichar está en el range de pares sustitutos ( 0xd800 -> 0xdfff ).
    2. Si se trata de un punto de código de par sustituto, luego revise todas las inputs en el dictionary de entidades y cambie los índices por 1 si son mayores que la location actual en la cadena (en términos de unichar s). Luego, incremente el contador de loops en 1 para omitir el socio de este par sustituto tal como se lo manejó ahora.
    3. Si no es un par sustituto, no haga nada.
  3. Haga un ciclo a través de todas las entidades y verifique que ninguno de ellos supere el final de la cadena. No deberían, pero solo en contra. Encontré algunos casos en los que Twitter devolvió datos falsos.

¡Espero que eso ayude! ¡También espero que algún día pueda abrir este código porque creo que sería increíblemente útil!

El problema es que cualquier carácter Unicode en su cadena con un valor Unicode de \ U10000 o superior aparecerá como dos caracteres en NSString .

Dado que desea formatear el hashtag, debe usar forms más dinámicas para get los valores de inicio y longitud. Use NSString rangeOfString para encontrar la location del carácter # . Use los resultados y la longitud de la cadena para get la longitud necesaria.

 NSString *text = @"@user1234 🍺🍺 #hashtag"; // text.length reported as 22 by NSLog as each emoji is 2 chars in length cell.textLabel.text = text; NSUInteger start = [text rangeOfString:@"#"]; if (start != NSNotFound) { NSUInteger length = text.length - start; NSRange *range = NSMakeRange(start, length); // apply formatting to TTTAttributedLabel [cell.textLabel addLinkToURL:[NSURL URLWithString:[NSString stringWithFormat:@"someaction://hashtag/%@", [cell.textLabel.text substringWithRange:range]]] withRange:range]; }