Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json Swift 4可解码和换行符\n_Json_Swift - Fatal编程技术网

Json Swift 4可解码和换行符\n

Json Swift 4可解码和换行符\n,json,swift,Json,Swift,iTunes搜索API返回的JSON有时包含换行符(\n) 这使得解码失败 您可以在此处看到一个示例: 卷曲“ 下面是我的精简域结构(实际响应中有更多内容): public struct iTunesSoftware: Codable { enum CodingKeys: String, CodingKey { case iTunesDescription = "description" } public var iTunesDescription:

iTunes搜索API返回的JSON有时包含换行符(\n)

这使得解码失败

您可以在此处看到一个示例:

卷曲“

下面是我的精简域结构(实际响应中有更多内容):

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服务的调用中获取数据对象

 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来覆盖字符串的解码


我是否遗漏了一些显而易见的东西?

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

tl;问题是我的测试会话mock从文件中读取json。我通常会做两个测试——实际的网络通话和文件通话。我错误地把一些垃圾复制到文件中。哦


谢谢你的回复。我猜你的一天比我的一天开始得好:)

实际上
JSONDecoder
应该正确解码包含换行符和空格字符的字符串。示例文字字符串中的反斜杠必须转义为
“description”:“此应用程序需要\\n iPad4,Mini 2”
,根据,控制字符在JSON字符串中无效,换行符必须转义为
\n
(在Swift字符串文字中为
\\n
)-您能否共享一个返回如此有问题的响应的URL?iTunes搜索API将返回该URL。这里有一个例子,你可以看到它。请看描述。curl“”在该响应中,我看不到字符串中的换行符,只有
\n
(即反斜杠字符后跟“n”)。@GeneDeLisa:您的上述测试代码创建了一个包含换行符(U+000A)的字符串。iTunesAPI的响应在字符串中不包含换行符,只包含反斜杠n序列,即转义的换行符。您上面的示例与iTunes API返回的结果不同将iTunes响应粘贴到中不会报告任何错误。你的问题一定是不同的。