如何在Swift中解码Instagram备份文件中的字符串?
解决iOS中Instagram备份JSON的字符串解码乱码问题
你的问题是典型的UTF-8字节被双重编码导致的乱码:JSON里的\u00d0\u0094这类转义序列,原本是西里尔字符的UTF-8字节,但JSON解码器会将每个\uXXXX解析为单独的Unicode码点,最终得到乱码字符串。
解决方案:自定义Codable解码逻辑
修改Media结构体的解码过程,将乱码字符串还原为正确的UTF-8编码内容:
struct BlogPost: Codable { let media: [Media] } struct Media: Codable { let title: String init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 先解码出被错误编码的字符串 let misencodedTitle = try container.decode(String.self, forKey: .title) // 将乱码字符串通过ISO-8859-1编码还原为原始UTF-8字节,再解码为正确字符串 guard let utf8Data = misencodedTitle.data(using: .isoLatin1), let correctTitle = String(data: utf8Data, encoding: .utf8) else { throw DecodingError.dataCorruptedError( forKey: .title, in: container, debugDescription: "无法修复标题的编码错误" ) } title = correctTitle } enum CodingKeys: String, CodingKey { case title } }
解析代码优化(避免强制解包)
建议替换原代码中的强制解包,增加错误处理:
do { guard let path = Bundle.main.path(forResource: "posts_1", ofType: "json"), let data = try? Data(contentsOf: URL(fileURLWithPath: path)) else { throw NSError(domain: "FileError", code: 1, userInfo: [NSLocalizedDescriptionKey: "无法读取JSON文件"]) } let result = try JSONDecoder().decode([BlogPost].self, from: data) print(result[0].media[0].title) // 输出:Дорогой друг } catch { print("解析错误:\(error)") }
原理说明
- 乱码字符串(如
ÐоÑогой дÑÑг)是UTF-8字节被当作ISO-8859-1(Latin-1)解码后的结果 - 通过
misencodedTitle.data(using: .isoLatin1)可以还原出原始的UTF-8字节序列 - 再用
String(data: utf8Data, encoding: .utf8)解码得到正确的西里尔文字符串
内容的提问来源于stack exchange,提问作者Roman Podymov
相关产品推荐
相关产品推荐

