“???”以字符串形式出现在 iOS 设备上,但不是模拟器

'???' Showing up in string on iOS Device, but not Simulator

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

这里有一些屏幕截图可以帮助解释我的意思:

在 iOS 模拟器上

在我的 iPhone 6 Plus(或任何 iOS 设备上)

提前致谢!

编辑:代码和日志

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

{"title":"The science behind Netflix’s first major redesign in four years"}`

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

{"title":"The science behind Netflix???s first major redesign in four years"}`

代码(我使用的是 Xamarin,所以它在 C# 中)

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

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

再次感谢!

更多细节

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

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

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

希望这对您有所帮助!谢谢你的包容!

您正在下载 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 或 [=19] =](取决于解码器的实现方式)。

根据 Xamarin 的 WebClient.DownloadString() documentation (which matches MSDN's documentation):

This method retrieves the specified resource. After it downloads the resource, the method uses the encoding specified in the WebClient.Encoding property to convert the resource to a String.

并且根据 Xamarin 的 WebClient.Encoding documentation (which is similar to MSDN's documentation):

When a string is downloaded using the System.Net.WebClient.DownloadString or System.Net.WebClient.DownloadStringAsync methods, System.Net.WebClient uses the System.Text.Encoding returned by this to convert the downloaded byte array into a string.

Xamarin 的文档没有说明 WebClient.Encoding 属性 的默认值是什么,但 MSDN 文档有说明:

The default value of this property is the encoding returned by Default.

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

Gets an encoding for the operating system's current ANSI code page.

Note:
Different computers can use different encodings as the default, and the default encoding can even change on a single computer. Therefore, data streamed from one computer to another or even retrieved at different times on the same computer might be translated incorrectly. In addition, the encoding returned by the Default property uses best-fit fallback to map unsupported characters to characters supported by the code page. For these two reasons, using the default encoding is generally not recommended. To ensure that encoded bytes are decoded properly, you should use a Unicode encoding, such as UTF8Encoding or UnicodeEncoding, with a preamble. Another option is to use a higher-level protocol to ensure that the same format is used for encoding and decoding.

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

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