MonoTouch - UIDevice.CurrentDevice.Name - UTF8
We noticed that UTF8 characters are not displayed correctly when used UIDevice.CurrentDevice.Name
in MonoTouch.
It comes out as "iPad 2 ??" if you use some special characters, for example, hold down the apostrop key on the iPad keyboard. (Sorry, I don't know the equivalent to show these symbols in windows)
Is there a recommended solution for getting the correct text? We don't mind converting to UTF8. I also tried to simulate this from a UITextField and it worked fine - no problem with UTF8.
The reason the problems are happening is because we are sending this text to the web service and causing problems with parsing the XML.
Here is the XmlWriter ( _parser.WriteRequest
) code snippet :
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 is passed from:
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
is recorded in Console.WriteLine
, it is turned on in mode #if DEBUG
. Request
is just a storage class with properties, sorry, easy to confuse with HttpWebRequest
.
I see??? in both XCode console and MonoDevelop console. I am also guessing that the server is receiving them strangely as well, since I am getting the error. Using UITextField.Text
with the same strange characters instead of a device description works fine without issue. This leads me to think the device description is the culprit.
EDIT: This has been fixed -
Encoding.UTF8.GetString (Encoding.ASCII.GetBytes(UIDevice.CurrentDevice.Name));
source to share
Ok, I think I know the problem. You create StringWriter
which always reports its encoding as UTF-16 (unless you override the property Encoding
). Then you take the string from StringWriter
(which starts with <?xml version="1.0" encoding="UTF-16" ?>
) and writes it to StreamWriter
, which will use UTF-8 by default. This mixture of encodings is causing the problem.
The easiest way is to change the code to pass Stream
directly to XmlWriter
- a MemoryStream
if you really want to, or just requestStream
. Thus, XmlWriter
can declare that it is using the exact encoding in which it actually writes the binary data - you don't have an intermediate step to screw things up.
Alternatively, you can create a subclass StringWriter
that allows you to specify the encoding. See this answer for example code.
source to share
MonoTouch simply calls the NSString.FromHandle
value it receives from the call UIDevice.CurrentDevice.Name
. This is how most string
are created from NSString
within all bindings.
This should give you string
that you can see it MonoDevelop (not ?
), so I can't rule out the error.
Can you tell us exactly how the device is named? if so, then open the bug report and we'll check it out.
source to share