Swift 4可解码和换行\ n

时间:2018-04-11 10:57:35

标签: json swift

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的解码?

我错过了一些明显的东西吗?

1 个答案:

答案 0 :(得分:1)

我在36年的编程中学到并重新学习的课程之一是“它不是你想象的那样”。我认为这是一个奇怪的可解码问题。所以,我从我的QuickSpec转到游乐场来隔离它。这不是坏事,但是凌晨5点,我当时只喝了一杯浓咖啡。

tl; dr问题是我的测试会话模拟,它从文件中读取json。我通常做两个测试 - 实际网络调用和文件。我错误地将一些垃圾复制到文件中。 D'哦!

感谢您的回复。我的猜测是,你的一天比我的开始更好:)