Swift 4 Decodable解析含换行符的iTunes搜索API JSON失败求助
解决iTunes API JSON含换行符导致Swift Decodable解析失败的问题
我之前也踩过这个坑!iTunes API返回的description字段偶尔会夹带未转义的换行/回车符,直接导致Swift的Decodable解析崩溃——毕竟这种格式不符合JSON的严格规范。下面给你几个实测有效的解决办法:
方法一:预处理原始数据,修复JSON格式
在把请求返回的原始Data传给JSONDecoder之前,先手动清理掉非法的换行符,把它们转成合法的JSON转义序列。写个工具函数就行:
func cleanITunesJSONData(_ data: Data) -> Data? { guard let jsonString = String(data: data, encoding: .utf8) else { print("无法将数据转换为UTF-8字符串") return nil } // 替换所有换行/回车符为JSON合法的转义序列 let cleanedString = jsonString .replacingOccurrences(of: "\r\n", with: "\\n") .replacingOccurrences(of: "\n", with: "\\n") .replacingOccurrences(of: "\r", with: "\\n") return cleanedString.data(using: .utf8) }
使用的时候,先清理数据再解析:
// 假设你已经获取到API返回的rawData guard let cleanedData = cleanITunesJSONData(rawData) else { return } do { let response = try JSONDecoder().decode(ITunesSearchResponse.self, from: cleanedData) // 处理解析后的结果 } catch { print("解析失败:\(error.localizedDescription)") }
方法二:用第三方库兼容松散JSON
如果你不想自己写预处理逻辑,可以试试SwiftyJSON,它对不严格的JSON兼容性更好,能直接解析带未转义换行的内容,之后再映射到你的Codable结构体:
import SwiftyJSON // 解析代码示例 if let json = try? JSON(data: rawData) { let description = json["results"][0]["description"].string let software = iTunesSoftware(iTunesDescription: description) // 处理数据 }
完整示例代码
为了让你更清楚,这里贴一个完整的请求+解析流程,包括定义完整的响应结构体:
import Foundation // 定义iTunes搜索响应的顶层结构体 public struct ITunesSearchResponse: Codable { let results: [iTunesSoftware] } public struct iTunesSoftware: Codable { enum CodingKeys: String, CodingKey { case iTunesDescription = "description" } public var iTunesDescription: String? } // 清理JSON数据的工具函数 func cleanITunesJSONData(_ data: Data) -> Data? { guard let jsonString = String(data: data, encoding: .utf8) else { print("数据转字符串失败") return nil } let cleanedString = jsonString .replacingOccurrences(of: "\r\n", with: "\\n") .replacingOccurrences(of: "\n", with: "\\n") .replacingOccurrences(of: "\r", with: "\\n") return cleanedString.data(using: .utf8) } // 发起请求并解析 func fetchRuismakerSoftware() { guard let url = URL(string: "https://itunes.apple.com/search?term=Ruismaker&entity=software&media=software&limit=1") else { print("无效URL") return } let task = URLSession.shared.dataTask(with: url) { rawData, _, error in guard let rawData = rawData, error == nil else { print("请求错误:\(error?.localizedDescription ?? "未知错误")") return } guard let cleanedData = cleanITunesJSONData(rawData) else { print("数据清理失败") return } do { let searchResponse = try JSONDecoder().decode(ITunesSearchResponse.self, from: cleanedData) if let software = searchResponse.results.first { print("软件描述:\(software.iTunesDescription ?? "无描述内容")") } } catch { print("解析错误:\(error)") } } task.resume() } // 调用请求方法 fetchRuismakerSoftware()
内容的提问来源于stack exchange,提问作者Gene De Lisa
相关产品推荐
相关产品推荐

