Swift使用JSONDecoder解码含日文的UTF-8 JSON乱码如何解决
Swift 解析含日文字符JSON乱码问题解决
原有问题代码
facilitiesService.facilitiesServerDataJson(urlToFetch: url_, jsoncompleted: { () in let responseData: Data = self.facilitiesService.UpdateJsonString.data(using: String.Encoding.utf8)! let decoder = JSONDecoder() let facilityDataListTmp = try decoder.decode([FacilityData].self, from: responseData)
异常表现
上述代码处理纯英文JSON时运行正常,当JSON包含日文字符时,解析得到的模型字段出现乱码:
nicopass.FacilityData( tn_newsid: 999900001, tn_midashi: "æºæã®å¤ã«ç¾ããç¥ç§ã®è¹ãã ã¼ã³ãã¦ããè¦ãã幸éã訪ããï¼è½å·®55mã§å壿ãã®ç¾ããçµ¶æ¯ãæããåç" )
该乱码可通过UTF-8解码工具还原为正常日文。
根因分析
乱码来自字符编码转换链路不匹配:
网络层返回的原始JSON是UTF-8编码的二进制数据,但facilitiesService内部提前将二进制数据转成UpdateJsonString字符串时,错误使用了单字节的*ISO-8859-1(Latin-1)*编码逐字节硬转,才生成了乱码字符串。后续代码再将这个本身就错误的字符串用UTF-8规则转回Data解析,相当于保留了编码错误,自然无法得到正确的多语言内容。
修复方案
按优先级选择以下两种方案即可解决:
- 最优修复:修改
facilitiesServerDataJson的实现逻辑,网络请求完成后直接返回原始的响应二进制Data,不要提前做二进制转字符串的操作,直接将原始Data传入JSONDecoder解析。这种方式从根源避免了中间转字符串带来的编码判断错误,可一次性兼容所有UTF-8支持的多语言字符,不会再出现非英文字符乱码问题。 - 兼容修复:如果暂时无法修改
facilitiesService的内部逻辑,可先将乱码字符串按Latin-1编码还原回原始二进制数据,再交给JSONDecoder解析,代码示例如下:
facilitiesService.facilitiesServerDataJson(urlToFetch: url_, jsoncompleted: { () in // 将错误生成的乱码字符串按Latin-1还原为原始二进制数据 guard let rawResponseData = self.facilitiesService.UpdateJsonString.data(using: .isoLatin1) else { // 此处添加数据异常的兜底处理逻辑 return } let decoder = JSONDecoder() let facilityDataListTmp = try decoder.decode([FacilityData].self, from: rawResponseData) // 后续正常业务逻辑 })
注意:代码中的强制解包
!在数据异常时会触发崩溃,生产环境建议替换为可选绑定做容错处理。
内容的提问来源于stack exchange,提问作者Kopera Marcel
相关产品推荐
相关产品推荐

