'???'在iOS设备上显示字符串,但不显示模拟器

时间:2015-05-22 17:21:14

标签: ios iphone string utf-8 ios-simulator

我发现具有相同文本和相同字体的相同单元格正在将'字符更改为???在设备上,但模拟器显示字符很好。其他一些特殊角色也会发生这种情况。

以下是一些帮助解释我的意思的截图:

在iOS模拟器上 enter image description here

在我的iPhone 6 Plus(或任何iOS设备)上 enter image description here

提前致谢!

编辑:代码和日志

来自服务器的JSON响应(在模拟器中)

  

{“title”:“Netflix四年来首次重大设计背后的科学”}`

来自服务器的JSON响应(在设备上)

  

{“title”:“Netflix四年来首次重大设计背后的科学”}`

CODE(我正在使用Xamarin,所以它在C#中)

var obj = JObject.Parse(response);
cell.TextLabel.Title = obj["title"].ToString();

显然,服务器的响应对于模拟器和设备是不同的。怎么会这样呢?他们都去了同一个地方,获得相同的信息......

再次感谢!

更多细节

使用C#的System.Net.WebClient的DownloadString()方法下载数据。

数据由我们自己的服务器(运行node.js和expressjs)提供

节点端点从我们的数据库获取数据,将其编码为JSON,然后使用res.send显示它。

希望这会有所帮助!谢谢你的支持!

1 个答案:

答案 0 :(得分:2)

您正在下载JSON数据。 JSON通常(但不是必须)以UTF-8编码。

有问题的JSON数据包含Unicode代码点U+2019 RIGHT SINGLE QUOTATION MARK,而不是U+0027 APOSTROPHE。代码点U+2019以UTF-8编码为字节0xE2 0x80 0x99

下载JSON时,原始字节在转换为String时不会被解释为UTF-8。这些字节在不支持字节0xE20x800x99的字符集中进行解释,因此它们每个都被转换为代码点U+003F QUESTION MARK或{{1 (取决于解码器的实现方式)。

根据Xamarin的WebClient.DownloadString()文档(与MSDN's documentation匹配):

  

此方法检索指定的资源。下载资源后,该方法使用U+FFFD REPLACEMENT CHARACTER属性中指定的编码将资源转换为WebClient.Encoding

根据Xamarin的WebClient.Encoding文档(类似于MSDN's documentation):

  

使用StringSystem.Net.WebClient.DownloadString方法下载字符串时,System.Net.WebClient.DownloadStringAsync使用此返回的System.Net.WebClient将下载的字节数组转换为字符串。

Xamarin的文档没有说明System.Text.Encoding属性的默认值是什么,但MSDN文档确实如此:

  

此属性的默认值是WebClient.Encoding返回的编码。

Default指的是System.Text.Encoding.Default属性:

  

获取操作系统的当前ANSI代码页的编码。

     

注意:
  不同的计算机可以使用不同的编码作为默认编码,默认编码甚至可以在一台计算机上更改。因此,从一台计算机流式传输到另一台计算机甚至在同一台计算机上不同时间检索的数据可能会被错误地翻译。此外,Default属性返回的编码使用最适合的回退将不支持的字符映射到支持的字符通过代码页。出于这两个原因,通常不建议使用默认编码。为了确保正确解码编码的字节,您应该使用Unicode编码(例如UTF8Encoding或UnicodeEncoding)和前导码。另一种选择是使用更高级别的协议来确保使用相同的格式进行编码和解码。

因此,iOS模拟器中Default使用的字符集(底层操作系统的字符集)与iOS设备中System.Text.Encoding.Default使用的字符集不同。这将解释您所看到的解码差异。

假设JSON在传输过程中确实被编码为UTF-8,您需要在调用System.Text.Encoding.Default之前将WebClient.Encoding属性设置为System.Text.Encoding.UTF8。然后它将在设备和模拟器上正确解码。