Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.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模型而不是根级别_Swift_Jsondecoder - Fatal编程技术网

将JSON解码为Swift模型而不是根级别

将JSON解码为Swift模型而不是根级别,swift,jsondecoder,Swift,Jsondecoder,我有以下型号: struct Article: Decodable { let title: String let description: String let imageURL: String private enum CodingKeys: String, CodingKey { case title case description case imageURL = "urlToImage" }

我有以下型号:

struct Article: Decodable {

    let title: String
    let description: String
    let imageURL: String

    private enum CodingKeys: String, CodingKey {
        case title
        case description
        case imageURL = "urlToImage"
    }

}

来自URL的JSON如下所示:

{
  status: "ok",
  totalResults: 70,
  articles: [
    {
      source: {
        id: null,
        name: "Oilprice.com"
      },
      author: "Tim Daiss",
      title: "$70 Oil Could Be Right Around The Corner | OilPrice.com - OilPrice.com",
      description: "A recent Bloomberg survey of oil analysts suggests that many believe oil could hit $70 per barrel in 2019, but are they just downplaying the bearish signals?",
      url: "https://oilprice.com/Energy/Crude-Oil/70-Oil-Could-Be-Right-Around-The-Corner.html",
      urlToImage: "https://d32r1sh890xpii.cloudfront.net/article/718x300/d7b8868e80d766d6a5d401219c65d6a0.jpg",
      publishedAt: "2019-01-01T00:00:08Z",
      content: "Oil markets have always been cyclical, and now even more so with advanced electronic trading, more speculation (which often results in wider oil price swings) and more producers, including the resurgence of U.S. oil production, now reaching over 11 million ba… [+4696 chars]"
    },
    {
      source: {
        id: "cnbc",
        name: "CNBC"
      },
      author: "Jordan Novet",
      title: "Activision Blizzard plans to fire its CFO for an unspecified cause - CNBC",
      description: "Shares of gaming company Activision Blizzard moved lower Monday after it announced plans to let go of its chief financial officer.",
      url: "https://www.cnbc.com/2018/12/31/activision-blizzard-plans-to-fire-its-cfo-for-an-unspecified-cause.html",
      urlToImage: "https://fm.cnbc.com/applications/cnbc.com/resources/img/editorial/2012/08/02/48465125-activision-200.1910x1000.jpg",
      publishedAt: "2018-12-31T23:18:17Z",
      content: "Activision Blizzard shares moved down 1 percent in after-hours trading on Monday after the company said that it has informed its chief financial officer, Spencer Neumann, that it plans to let him go. For now he has been placed on a paid leave of absence. div … [+950 chars]"
    }
  ]
}
我想要的只是文章中的值。如何使用Swift 4 JSONDecoder获取它


我知道如何创建父结构,然后在父结构中创建“articles”属性。但是如果没有父结构,我怎么做呢

您可以尝试将
JSONSerialization
JSONDecoder

do
{
    let tr = try JSONSerialization.jsonObject(with:data, options:[]) as! [String:Any] 
    guard let content =  tr["articles"] else { return }
    let articlesData = try JSONSerialization.data(withJSONObject:content, options: [])
    let res = try JSONDecoder().decode([Article].self, from: articlesData) 
    print(res) 
}
catch 
{
    print(error)
}

您可以尝试将
JSONSerialization
JSONDecoder

do
{
    let tr = try JSONSerialization.jsonObject(with:data, options:[]) as! [String:Any] 
    guard let content =  tr["articles"] else { return }
    let articlesData = try JSONSerialization.data(withJSONObject:content, options: [])
    let res = try JSONDecoder().decode([Article].self, from: articlesData) 
    print(res) 
}
catch 
{
    print(error)
}

单独使用JSONDecoder,在没有某种外部结构的情况下无法解码,因为您的结果将是一个Article数组,它是一个外部实体。因此,仅仅定义条款是不够的

如果您不喜欢声明一个除了向下搜索到
“articles”
键之外不需要的外部结构,那么只在向下搜索到
“articles”
键的有限范围内临时声明它就可以很容易地解决这个问题。因此,程序的其余部分保留了Article结构,但外部结构不存在

例如:

struct Article: Decodable {
    // ... your code here ...
}
func getArticles(_ d:Data) -> [Article] {
    struct Articles: Decodable { // this struct is temporary
        let articles:[Article]
    }
    return try! JSONDecoder().decode(Articles.self, from: d).articles
}

其他代码现在可以看到文章结构,可以调用
getArticles
解析JSON并接收文章数组,但其他代码永远不知道(也永远不会发现)存在额外的文章结构;它只是暂时存在于
getArticles
函数中,作为一种局部变量。它并不比在函数体中临时创建的任何其他局部变量更令人反感。

仅使用JSONDecoder,您无法在没有某种外部结构的情况下解码,因为您的结果将是一个文章数组,它是一个外部实体。因此,仅仅定义条款是不够的

如果您不喜欢声明一个除了向下搜索到
“articles”
键之外不需要的外部结构,那么只在向下搜索到
“articles”
键的有限范围内临时声明它就可以很容易地解决这个问题。因此,程序的其余部分保留了Article结构,但外部结构不存在

例如:

struct Article: Decodable {
    // ... your code here ...
}
func getArticles(_ d:Data) -> [Article] {
    struct Articles: Decodable { // this struct is temporary
        let articles:[Article]
    }
    return try! JSONDecoder().decode(Articles.self, from: d).articles
}

其他代码现在可以看到文章结构,可以调用
getArticles
解析JSON并接收文章数组,但其他代码永远不知道(也永远不会发现)存在额外的文章结构;它只是暂时存在于
getArticles
函数中,作为一种局部变量。它并不比函数体中临时创建的任何其他局部变量更令人反感。

考虑重新构造数据。您需要构造数据模型以匹配JSON数据的数据结构。只能包含所需内容,但必须包含要访问的每个父级或属性级别。以维基百科API中的以下示例为例。它打印出JSON数据结构中三个层次的title属性。从JSON示例代码中可以看出,它省略了几个属性,但它包含了访问所需属性所需的每个父级

JSON示例:

{
"batchcomplete": "",
"continue": {
    "sroffset": 10,
    "continue": "-||"
},
"query": {
    "searchinfo": {
        "totalhits": 30349
    },
    "search": [
        {
            "ns": 0,
            "title": "Swift",
            "pageid": 219023,
            "size": 13896,
            "wordcount": 1496,
            "snippet": "The <span class=\"searchmatch\">swifts</span> are a family, Apodidae, of highly aerial birds. They are superficially similar to swallows, but are not closely related to any passerine species",
            "timestamp": "2018-12-28T21:29:44Z"
        },
        {
            "ns": 0,
            "title": "Swift (programming language)",
            "pageid": 42946389,
            "size": 49365,
            "wordcount": 5244,
            "snippet": "2015. <span class=\"searchmatch\">Swift</span> 3.0 was released on September 13, 2016. <span class=\"searchmatch\">Swift</span> <span class=\"searchmatch\">4</span>.0 was released on September 19, 2017. <span class=\"searchmatch\">Swift</span> <span class=\"searchmatch\">4</span>.1 was released on March 29, 2018. <span class=\"searchmatch\">Swift</span> won first",
            "timestamp": "2018-12-19T02:52:33Z"
        },
        {
            "ns": 0,
            "title": "Taylor Swift",
            "pageid": 5422144,
            "size": 237225,
            "wordcount": 18505,
            "snippet": "Taylor Alison <span class=\"searchmatch\">Swift</span> (born December 13, 1989) is an American singer-songwriter. One of the world's leading contemporary recording artists, she is known",
            "timestamp": "2018-12-26T21:55:51Z"
        },

考虑重组数据。您需要构造数据模型以匹配JSON数据的数据结构。只能包含所需内容,但必须包含要访问的每个父级或属性级别。以维基百科API中的以下示例为例。它打印出JSON数据结构中三个层次的title属性。从JSON示例代码中可以看出,它省略了几个属性,但它包含了访问所需属性所需的每个父级

JSON示例:

{
"batchcomplete": "",
"continue": {
    "sroffset": 10,
    "continue": "-||"
},
"query": {
    "searchinfo": {
        "totalhits": 30349
    },
    "search": [
        {
            "ns": 0,
            "title": "Swift",
            "pageid": 219023,
            "size": 13896,
            "wordcount": 1496,
            "snippet": "The <span class=\"searchmatch\">swifts</span> are a family, Apodidae, of highly aerial birds. They are superficially similar to swallows, but are not closely related to any passerine species",
            "timestamp": "2018-12-28T21:29:44Z"
        },
        {
            "ns": 0,
            "title": "Swift (programming language)",
            "pageid": 42946389,
            "size": 49365,
            "wordcount": 5244,
            "snippet": "2015. <span class=\"searchmatch\">Swift</span> 3.0 was released on September 13, 2016. <span class=\"searchmatch\">Swift</span> <span class=\"searchmatch\">4</span>.0 was released on September 19, 2017. <span class=\"searchmatch\">Swift</span> <span class=\"searchmatch\">4</span>.1 was released on March 29, 2018. <span class=\"searchmatch\">Swift</span> won first",
            "timestamp": "2018-12-19T02:52:33Z"
        },
        {
            "ns": 0,
            "title": "Taylor Swift",
            "pageid": 5422144,
            "size": 237225,
            "wordcount": 18505,
            "snippet": "Taylor Alison <span class=\"searchmatch\">Swift</span> (born December 13, 1989) is an American singer-songwriter. One of the world's leading contemporary recording artists, she is known",
            "timestamp": "2018-12-26T21:55:51Z"
        },

@印象7VX这是一种古老的做事方式。我正在寻找JSONDecoder方式。我明白了。您正在尝试解析其中的一部分,而不是整个内容。有趣。难道你不想要一个父结构,这样你就可以使用
totalResults
以及
status
?“来自URL的JSON是这样的”不,它不是。您显示的不是有效的JSON。仅使用JSONDecoder,您无法在没有某种外部结构的情况下解码,因为您的结果将是一个Article数组,它是一个外部实体。因此,仅仅定义文章是不够的。@impression7vx这是一种古老的做事方式。我正在寻找JSONDecoder方式。我明白了。您正在尝试解析其中的一部分,而不是整个内容。有趣。难道你不想要一个父结构,这样你就可以使用
totalResults
以及
status
?“来自URL的JSON是这样的”不,它不是。您显示的不是有效的JSON。仅使用JSONDecoder,您无法在没有某种外部结构的情况下解码,因为您的结果将是一个Article数组,它是一个外部实体。因此,仅仅定义条款是不够的。