代码之家  ›  专栏  ›  技术社区  ›  john doe

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

  •  -1
  • john doe  · 技术社区  · 6 年前

    我有以下型号:

    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]"
    },
    

    我想要的只是 文章 关键。如何使用Swift4 JSondecoder获得它。

    我知道如何通过创建父结构,然后在父结构内创建“项目”属性来实现这一点。但是如果没有父结构,我该怎么做呢?

    3 回复  |  直到 6 年前
        1
  •  1
  •   matt    6 年前

    单独使用jsondecoder,没有某种外部结构就无法解码,因为您的结果将是 数组 属于外部实体的第条。因此,仅仅定义一个物品永远是不够的。

    如果您不喜欢声明一个外部结构,您不需要为任何其他目的而进行深入到 "articles" 密钥,只需声明即可轻松解决 暂时地 在有限的范围内进行深入到 “文章” 关键。因此,程序的其余部分保留了项目结构,但外部结构不存在。

    例如:

    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并接收项目数组,但是其他代码永远不知道(也永远不知道)额外的项目结构存在;它只在 获得文章 作为一种局部函数。它并不比在函数体中临时创建的任何其他局部变量更令人反感。

        2
  •  0
  •   Shehata Gamal    6 年前

    你可以尝试结合 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)
    }
    
        3
  •  0
  •   Gustavo Picciuto    6 年前

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

    import UIKit
    
    struct Item: Decodable {
        var title: String
    }
    
    struct Search: Decodable {
        var search: [Item]
    }
    
    struct Result: Decodable {
        var query: Search
    }
    
    func getSearchResults(){
        let url = URL(string: "https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=swift%204&utf8=&format=json")!
    
        URLSession.shared.dataTask(with: url) { (data, response, error) in
        if let urlResponse = response as? HTTPURLResponse, urlResponse.statusCode == 200 {
            guard let data = data else { return }
            do {
                let results = try JSONDecoder().decode(Result.self, from: data)
                for item in results.query.search {
                    print(item.title)
                }
            } catch let error as NSError {
                print("error: \(error)")
            }
        }
    }.resume()
    }
    getSearchResults()
    

    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"
            },
    

    这是打印输出:

    //Swift
    //Swift (programming language)
    //Taylor Swift