NSNonLossyASCIIStringEncoding возвращает nil

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

Он работает отлично, когда я отправил emojis с простым текстом, но он возвращает nil, когда в строку добавлен специальный символ. Как заставить его работать?

Код:

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

Ответ 1

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

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

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

введите описание изображения здесь

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

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

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

Если данные были закодированы в ascii, для преобразования он использовал бы буквенный ascii hex. Итак, \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?


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

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

Ответ 2

Если вы просто хотите иметь emojis в своем коде как литералы, есть два варианта:

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

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

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

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

Обе печати: 😀😎 + _) (& # &) # &) $& $) & $) ^ #%!! # $%!

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