NSNonLossyASCIIStringEncoding возвращает ноль

Я работаю над эмодзи по умолчанию в iOS. Я могу успешно кодировать и декодировать эмодзи по умолчанию, используя кодирование NSNonLossyASCIIStringEncoding.

Работает нормально, когда я отправляю смайлики с простым текстом, но возвращает ноль, когда в строку добавляется какой-то специальный символ. Как мне заставить это работать?

Код:

    testString=":;Hello \ud83d\ude09\ud83d\ude00 ., <> /?\";
    NSData *data = [testString dataUsingEncoding:NSUTF8StringEncoding];
    NSString *strBody = [[NSString alloc] initWithData:data encoding:NSNonLossyASCIIStringEncoding]; 
    // here strBody is nil

2 ответа

Решение

Проблема связана с различными кодировками, которые вы использовали для кодирования и декодирования.

 testString=":;Hello \ud83d\ude09\ud83d\ude00 ., <> /?\";
 NSData *data = [testString dataUsingEncoding:NSUTF8StringEncoding];

Здесь вы преобразовали строку в данные, используя кодировку UTF8. Это означает, что он преобразует символы Unicode в 1-4 байта в зависимости от используемого символа Unicode. Например, \ude09 будет переводиться в ED B8 89. Объяснение того же доступно в вики. В основном это использует следующую технику:

Теперь, если вы попытаетесь декодировать это в строку, используя кодировку ascii, как показано ниже

   NSString *strBody = [[NSString alloc] initWithData:data encoding:NSNonLossyASCIIStringEncoding]; 

Вышеприведенное обязательно приведет к сбою, поскольку не может декодировать ED B8 89 или аналогичные данные Unicode в строку ascii. Вот почему он возвращает ошибку.

Если бы данные были закодированы в ascii, то для преобразования использовался бы буквенный шестнадцатеричный ascii. Так что \ude09 стал бы "5c 75 64 65 30 39"

Таким образом, правильное преобразование будет:

    testString=":;Hello \ud83d\ude09\ud83d\ude00 ., <> /?\";
    NSData *data = [testString dataUsingEncoding:NSNonLossyASCIIStringEncoding];
    NSString *strBody = [[NSString alloc] initWithData:data encoding:NSNonLossyASCIIStringEncoding]; 

Вопрос для вас: почему вы хотите, чтобы он кодировался как UTF8 и декодировался как ASCII?


Для смайликов, пожалуйста, попробуйте ниже

        testString=":;Hello \\ud83d\\ude09\\ud83d\\ude00 ., <> /?";
        NSData *data = [testString dataUsingEncoding:NSUTF8StringEncoding];
        NSString *strBody = [[NSString alloc] initWithData:data encoding:NSNonLossyASCIIStringEncoding]; 

Если вы просто хотите, чтобы эмодзи в вашем коде были литералами, есть два варианта:

А. Просто сделай это:

NSString *hello = @"+_)(&#&)#&)$&$)&$)^#%!!#$%!";
NSLog(@"%@", hello);

Б. Добавьте коды как UTF32

NSString *hello = @"\U0001F600\U0001F60E+_)(&#&)#&)$&$)&$)^#%!!#$%!";
NSLog(@"%@", hello);

Оба отпечатка: +_)(& # &)#&)$&$)&$)^#%!!#$%!

Я действительно не понимаю твою проблему.

Другие вопросы по тегам