iTunes搜索API返回有时包含换行符的JSON(\ n)。
这使得解码失败。
你可以在这里看到一个例子:
curl" https://itunes.apple.com/search?term=Ruismaker&entity=software&media=software&limit=1"
这是我的精简版(在实际响应中还有更多)域结构:
public struct iTunesSoftware: Codable {
enum CodingKeys: String, CodingKey {
case iTunesDescription = "description"
}
public var iTunesDescription: String?
}
以下是一些测试代码:
let jstring = """
{
"description": "This App requires \n iPad 4, Mini 2",
}
"""
// try it with and without the newline to see the problem
let encoded = String(jstring.filter { !" \n\t\r".contains($0) })
let encodedData = encoded.data(using: .utf8)!
//let encodedData = jstring.data(using: .utf8)!
然后解码:
let decoder = JSONDecoder()
do {
let app = try decoder.decode(iTunesSoftware.self, from: encodedData)
print(app)
} catch {
print(error)
}
但实际上,您从调用REST服务中获取Data对象。
let task = session.dataTask(with: url) {
(data, _, err) -> Void in
// I have a Data object, not a String here.
// I can do this:
if let s = String(data: data, encoding: .utf8) {
filter it, turn it back into a Data object, then decode
let encoded = String(s.filter { !" \n\t\r".contains($0) })
let encodedData = encoded.data(using: .utf8)
var encodedData: Data?
if let s = String(data: responseData, encoding: .utf8) {
// filter it, turn it back into a Data object, then decode
let encoded = String(s.filter { !" \n\t\r".contains($0) })
encodedData = encoded.data(using: .utf8)
}
guard let theData = encodedData else {
return
}
// and then later:
let app = try decoder.decode(iTunesSoftware.self, from: theData)
所以,我的问题是:真的吗?这是一个常见的用例 - 它来自Apple REST服务。你会认为解码器会允许你设置一些东西来忽略控制字符。
JSONDecoder具有各种策略属性,例如:
open var dataDecodingStrategy: JSONDecoder.DataDecodingStrategy
您是否应该创建自定义KeyedDecodingContainer以覆盖String的解码?
我错过了一些明显的东西吗?
答案 0 :(得分:1)
我在36年的编程中学到并重新学习的课程之一是“它不是你想象的那样”。我认为这是一个奇怪的可解码问题。所以,我从我的QuickSpec转到游乐场来隔离它。这不是坏事,但是凌晨5点,我当时只喝了一杯浓咖啡。
tl; dr问题是我的测试会话模拟,它从文件中读取json。我通常做两个测试 - 实际网络调用和文件。我错误地将一些垃圾复制到文件中。 D'哦!
感谢您的回复。我的猜测是,你的一天比我的开始更好:)