Символы Emoji не могут быть закодированы в JSON

у меня есть UITextView который я называю messageField. Данные внутри messageField is POST - ed на сервер в формате JSON. Когда пользователь вводит символ Emoji, у меня возникают проблемы с кодированием данных в JSON. Я думаю, что Emoji использует кодировку Unicode.

есть ли способ кодировать символ Emoji в JSON? И обратно из JSON в Emoji для отображения в UILabel?

6 ответов


изменить - 2016-03-03 обратите внимание, что этот ответ был написан в 2011 году и больше не может быть актуальным.

символы Emoji - это просто определенный шрифт, используемый для отображения определенных кодовых точек unicode. iOS использует одну из областей частного использования Unicode для кодовых точек, специфичных для Emoji. Единственный способ просмотреть эти "символы" как Emoji - это иметь доступный шрифт Emoji, а также машину, которая знает, как переключаться с шрифта текста по умолчанию (например, Helvetica) к шрифту emoji.

Я не знаю, как вы кодируете свой JSON, но поскольку Emoji-это просто текст, не должно быть никаких проблем, пока вы транспортируете текст в формате, удобном для Unicode, таком как UTF-8 или UTF-16. Вы не увидите его на стороне сервера или в базе данных (если вы не просматриваете данные с предыдущими предварительными условиями), но вы должны иметь возможность отправлять те же необработанные байты назад, и он должен выглядеть одинаково.

вот некоторые сообщения, которые могут немного помочь еще:


Я использую приведенный ниже код для кодирования символа emoji

NSString *uniText = [NSString stringWithUTF8String:[textview.text UTF8String]]; 
NSData *msgData = [uniText dataUsingEncoding:NSNonLossyASCIIStringEncoding]; 
NSString *goodMsg = [[NSString alloc] initWithData:msgData encoding:NSUTF8StringEncoding] ;

и ниже код для декодирования и отображения в UILabel

const char *jsonString = [body UTF8String]; 
NSData *jsonData = [NSData dataWithBytes:jsonString length:strlen(jsonString)]; 
NSString *goodMsg = [[NSString alloc] initWithData:jsonData encoding:NSNonLossyASCIIStringEncoding];

У меня была та же проблема, после копания в течение нескольких часов и, наконец, нашел этот ответ, который работает для меня: https://stackoverflow.com/a/8339255/1090945

Если вы используете rails в качестве сервера, это все, что вам нужно сделать. Не нужно ничего делать в ios/xcode, просто передайте NSString, не делая никаких кодировок UTF8 / 16 на сервер.

Postegre сохраняет код правильно, это просто когда вы отправляете ответ json обратно на свой клиент ios, предполагая вы делаете рендеринг json:@message, кодировка json имеет проблему.

вы можете проверить, есть ли у вас проблема с кодировкой json в консоли rails, выполнив простой тест:

test = {"smiley" => " u{1f604}"} тест.to_json

если он печатает " {\"smiley\":\ " \uf604\"} " (обратите внимание, что 1 потерян), то у вас есть эта проблема. и патч из ссылки исправит это.


спасибо @Karu, редактируя ваш ответ, я использую этот код:

кодирование для отправки на сервер:

NSString *uniText = [NSString stringWithUTF8String:[text_to_send UTF8String]];

NSData *msgData = [uniText dataUsingEncoding:NSNonLossyASCIIStringEncoding];

NSString *str = [[NSString alloc] initWithData:msgData encoding:NSUTF8StringEncoding];

декодировать для получения и отображения текста emoji:

NSData *newdata = [received_string dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

NSString *mystring = [[NSString alloc] initWithData:newdata encoding:NSNonLossyASCIIStringEncoding];

NSString *finalString= @"";

if (mystring) {
   finalString = mystring;
}else{
   finalString = received_string;
}

этот код работает идеально на iOS 9


одна вещь, которую нужно знать с Emoji-если ваш кодировщик json настроен на получение ASCII-вывода (т. е. с использованием формата символов \u), некоторые символы Emoji сломаются, потому что они используют более двух байтов и, таким образом, не вписываются в 4 шестнадцатеричные цифры.

поэтому в python, например, обязательно используйте:

json.dumps(<object containing emoji strings>, ensure_ascii=False)

Обновление Swift & Objective C

Если вы хотите отправить отправить элемент emoji через JSON, сначала вам нужно сформировать DB в UTF-8, а в IOS вам нужно кодировать для NSUTF8StringEncoding. Поэтому сначала убедитесь, что ваш DB formate в UTF-8 затем кодирует параметры в NSUTF8StringEncoding.Вот пример запроса при отправке сообщения.

    let post:NSString = parameters!
    let url:NSURL = NSURL(string: serverURL!)!
    let postData:NSData = post.dataUsingEncoding(NSUTF8StringEncoding)! // Change Here
    let postLength:NSString = String( postData.length )
    let request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "POST"
    request.HTTPBody = postData
    request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.setValue("*/*", forHTTPHeaderField: "Accept")
    return request

но вам не нужно декодировать NSUTF8StringEncoding в iOS.Потому что, согласно документации apple, он декодирует 5 кодирования.

данные должны находиться в одной из 5 поддерживаемых кодировок, перечисленных в Спецификация json-файле: формат UTF-8, кодировке UTF-16LE, кодировка UTF-16BE, в UTF-32LE, в UTF-32BE. Этот данные могут иметь или не иметь спецификации. Наиболее эффективное кодирование парсинг UTF-8, поэтому если у вас есть выбор в кодировку данных, передаваемых для этого метода используйте UTF-8.

https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSJSONSerialization_Class/#//apple_ref/occ/clm/NSJSONSerialization/JSONObjectWithData:options:error: