29 мар. 2016 г.

Unicode последовательности и NSString. Unicode composed sequence and NSString.

Завязался с оперированием эмотиконками из набора Unicode символов строке NSString. Одна из сложностей с Unicode в том, что он бывает не только UTF-8, но и UTF-16, и UTF-32. В данном случае стояла задача удаления последней эмотиконки из строки текста. Посимвольное удаление не работает, поскольку даже при том, что для этих значков используется UTF-32 (то есть длина символа понятна — 4 байта), существую так называемые Композиционные последовательности Unicode (вольный перевод). Например, такой неоднозначный значок как "👨‍👨‍👦‍👦"(Family: MAN, MAN, BOY, BOY) состоит из 7 символов: U+1F468 U+200D U+1F468 U+200D U+1F466 U+200D U+1F466. Соответственно, чтобы удалить одну иконку, нужно удалять до 7 символов. Причем от иконки к иконке их количество меняется. У NSString для этих случаев есть набор методов для работы с такими последовательностями. Они описываются в статье "NSString and Unicode", поэтому их все я тут описывать не буду. Конкретная задача удаления последней иконки, вне зависимости от количества составляющих ее Unicode символов была решена так:

NSRange rng = [str rangeOfComposedCharacterSequenceAtIndex:[str length]-1];
        str = [str substringToIndex:rng.location];

В частности, здесь использован метод rangeOfComposedCharacterSequenceAtIndex, который возвращает NSRange, указывающий на первый символ последовательности и на длину самой последовательности. Дальнейшее оперирование производится как с обычными символами.