MonoTouch - UIDevice.CurrentDevice.Name - UTF8 - PullRequest
3 голосов
/ 27 марта 2012

Мы заметили, что символы UTF8 не отображаются правильно при использовании UIDevice.CurrentDevice.Name в MonoTouch.

Он появляется как «iPad 2 ??», если вы используете некоторые из специальных символов, таких какудерживая клавишу апостроф на клавиатуре iPad.(Извините, не знаю эквивалента для отображения этих символов в окнах)

Есть ли рекомендуемое решение для получения правильного текста?Мы не против самих перейти на UTF8.Я также пытался смоделировать это из UITextField, и он работал нормально - никаких проблем с UTF8.

Причина, по которой это вызывает проблемы, заключается в том, что мы отправляем этот текст в веб-службу, и это вызывает проблемы с синтаксическим анализом XML.

Вот фрагмент кода XmlWriter (_parser.WriteRequest):

            using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, new XmlWriterSettings 
                { 
#if DEBUG
                    Indent = true,
#else
                    Indent = false, NewLineHandling = NewLineHandling.None, 
#endif
                    OmitXmlDeclaration = true 
                }))
            {
                xmlWriter.WriteStartDocument();
                xmlWriter.WriteStartElement("REQUEST");
                xmlWriter.WriteAttributeString("TYPE", "EXAMPLE");
                xmlWriter.WriteEndElement();
                xmlWriter.WriteEndDocument();
            }

TextWriter передается из:

public Response MakeRequest(Request request)
{
    var httpRequest = CreateRequest(request);

    WriteRequest(httpRequest.GetRequestStream(), request);

    using (var httpResponse = httpRequest.GetResponse() as HttpWebResponse)
    {
        using (var responseStream = httpResponse.GetResponseStream())
        {
            var response = new Response();
            ReadResponse(response, responseStream);
            return response;
        }
    }
}

private void WriteRequest(Stream requestStream, Request request)
{
    if (request.Type == null)
    {
        throw new InvalidOperationException("Request Type was null!");
    }

    if (_logger.Enabled)
    {
        var builder = new StringBuilder();
        using (var writer = new StringWriter(builder, CultureInfo.InvariantCulture))
        {
            _parser.WriteRequest(writer, request);
        }
        _logger.Log("REQUEST: " + builder.ToString());

        using (requestStream)
        {
            using (StreamWriter writer = new StreamWriter(requestStream))
            {
                writer.Write(builder.ToString());
            }
        }
    }
    else
    {
        using (requestStream)
        {
            using (StreamWriter writer = new StreamWriter(requestStream))
            {
                _parser.WriteRequest(writer, request);
            }
        }
    }
}

_logger пишет в Console.WriteLine, он включен в режиме #if DEBUG.Request это просто класс хранения со свойствами, извините, его легко спутать с HttpWebRequest.

Я вижу ??как в консоли XCode, так и в консоли MonoDevelop.Я также предполагаю, что сервер получает их странным образом, так как я получаю сообщение об ошибке.Использование UITextField.Text с такими же странными символами вместо описания устройства работает без проблем.Это заставляет меня думать, что описание устройства является виновником.

РЕДАКТИРОВАТЬ: это исправлено -

Encoding.UTF8.GetString (Encoding.ASCII.GetBytes(UIDevice.CurrentDevice.Name));

Ответы [ 2 ]

3 голосов
/ 27 марта 2012

Хорошо, я думаю, что знаю проблему. Вы создаете StringWriter, который всегда сообщает его кодировку как UTF-16 (если вы не переопределите свойство Encoding). Затем вы берете строку из этого StringWriter (которая начинается с <?xml version="1.0" encoding="UTF-16" ?>) и записываете ее в StreamWriter, который по умолчанию будет UTF-8. Эта смесь кодировок вызывает проблему.

Самый простой подход - изменить код так, чтобы он передавал Stream непосредственно в XmlWriter - MemoryStream, если вы действительно хотите, или просто requestStream. Таким образом, XmlWriter может объявить, что использует точную кодировку, в которую фактически записывает двоичные данные - у вас нет промежуточного шага, чтобы все испортить.

В качестве альтернативы, вы можете создать подкласс StringWriter, который позволит вам указать кодировку. См. этот ответ для примера кода.

1 голос
/ 27 марта 2012

MonoTouch просто вызывает NSString.FromHandle на значение, которое он получает от вызова на UIDevice.CurrentDevice.Name.Это так же, как большинство string создаются из NSString внутри всех привязок.

Это должно дать вам string, что вы можете видеть его MonoDevelop (no ?), поэтому я не могу исключитьЖук.

Можете ли вы сказать нам, как именно устройство названо?если это так, пожалуйста, откройте отчет об ошибке , и мы проверим эту возможность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...