如何在字典的嵌套数组中访问“名称”

时间:2020-08-28 21:30:29

标签: json swift

以下是用于解析新闻API中的JSON数据的代码。如何在不使用编码协议的情况下访问数组源部分中的“名称”?从网站检索时,这就是json数据的样子。

[{
    author = "Louise Matsakis";
    content = "When the novelcoronavirus was first discovered in China last winter, the country responded aggressively, placing tens of millions of people into strict lockdown. As Covid-19 spread from Wuhan to the \U2026 [+3647 chars]";
    description = "In China, the messaging platform blocked thousands of keywords related to the virus, a new report reveals.";
    publishedAt = "2020-08-27T21:30:00Z";
    source =     {
        id = wired;
        name = Wired;
    };
    title = "How WeChat Censored the Coronavirus Pandemic";
    url = "https://www.wired.com/story/wechat-chinese-internet-censorship-coronavirus/";
    urlToImage = "https://media.wired.com/photos/5f46ababa73ba18581f3aac0/191:100/w_1280,c_limit/Security_China_1228043332.jpg";
}, {
    author = "Kate Dore on Two Cents, shared by Kate Dore to Lifehacker";
    content = "As college students return to school, some have noticed a new line item on their bill: a coronavirus fee. With new costs for screening, testing, and safety configurations, the New York Times reports \U2026 [+1857 chars]";
    description = "As college students return to school, some have noticed a new line item on their bill: a coronavirus fee. With new costs for screening, testing, and safety configurations, the New York Times reports some colleges and universities are passing part of the expen\U2026";
    publishedAt = "2020-08-17T20:00:00Z";
    source =     {
        id = "<null>";
        name = "Lifehacker.com";
    };
    title = "What to Know About Coronavirus Charges on Your College Bill";
    url = "https://twocents.lifehacker.com/what-to-know-about-coronavirus-charges-on-your-college-1844752829";
    urlToImage = "https://i.kinja-img.com/gawker-media/image/upload/c_fill,f_auto,fl_progressive,g_center,h_675,pg_1,q_80,w_1200/zeeqev5k6mmyauyqlfx8.jpg";
}, {
    author = "Jason DeParle";
    content = "Money helps children in part because of what it buys food, housing, better schools, health care and summer camps. But it also important in a less obvious way: It reduces stress, which can reach toxic\U2026 [+2508 chars]";
    description = "The virus doesn\U2019t sicken kids as much as adults. But it can still destroy their futures. A child allowance would help.";
    publishedAt = "2020-08-22T18:55:36Z";
    source =     {
        id = "<null>";
        name = "New York Times";
    };
    title = "The Coronavirus Generation";
    url = "https://www.nytimes.com/2020/08/22/sunday-review/coronavirus-poverty-child-allowance.html";
    urlToImage = "https://static01.nyt.com/images/2020/08/23/opinion/sunday/21Deparle/21Deparle-facebookJumbo.jpg";
}, 
func parseData(data:Data)-> [Articles]   {
     var articles: [Articles]? = [] // holds parsed data

        do {
            let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
            
            let jsonArticles = jsonResult?["articles"] as? [AnyObject] ?? [] // gets first head of json file and dteremines weather
          
            for jsonArticle in jsonArticles{ // captures data and converts to article type
         let article = Articles()
         article.author = jsonArticle["author"] as? String
         article.title = jsonArticle["description"] as? String
         article.publishedAt = jsonArticle["publishedAt"] as? String
         articles?.append(article) //put article data in the array
            }
        

1 个答案:

答案 0 :(得分:1)

所以,让我们开始吧,“示例源”不是JSON,因此我重新设置了格式,以便可以对其进行解析

[
    {
        "author":"Louise Matsakis",
        "content":"When the novelcoronavirus was first discovered in China last winter, the country responded aggressively, placing tens of millions of people into strict lockdown. As Covid-19 spread from Wuhan to the \\U2026 [+3647 chars]",
        "description":"In China, the messaging platform blocked thousands of keywords related to the virus, a new report reveals.",
        "publishedAt":"2020-08-27T21:30:00Z",
        "source":{
            "id":"wired",
            "name":"Wired"
        },
        "title":"How WeChat Censored the Coronavirus Pandemic",
        "url":"https://www.wired.com/story/wechat-chinese-internet-censorship-coronavirus/",
        "urlToImage":"https://media.wired.com/photos/5f46ababa73ba18581f3aac0/191:100/w_1280,c_limit/Security_China_1228043332.jpg"
    }
]

然后,我使用Playground构建了一系列表示JSON结构的结构,使它们符合Decodable,以便更轻松地解析JSON

struct Source: Decodable {
    let id: String
    let name: String
}

struct Article: Decodable {
    let author: String
    let content: String
    let description: String
    let publishedAt: Date
    let source: Source
    let title: String
    let url: URL
    let urlToImage: URL
}

然后我使用Swift的JSONDecoder来解析内容

let source = Bundle.main.url(forResource: "Source", withExtension: "json")!
do {
    let data = try Data(contentsOf: source)
    let decoder  = JSONDecoder()
    decoder.dateDecodingStrategy = .iso8601
    let articles = try decoder.decode([Article].self, from: data)
    
    for article in articles {
        print(article.source.name)
    }
    
} catch let error {
    print("\(error)")
}

然后将打印Wired

跟进...

它不是plist文件。这直接来自新闻API。

好吧,经过一番谷歌搜索之后,您似乎是说newsapi.org

因此,在使用...进行了一些测试之后

    let url = URL(string: "https://newsapi.org/v2/top-headlines?country=au&apiKey=...")!
    let task = URLSession.shared.downloadTask(with: url) { localURL, urlResponse, error in
        print("\(error)")
        if let localURL = localURL {
            if let string = try? String(contentsOf: localURL) {
                print(string)
            }
        }
    }

我能够收到以下回复...

{
    "status":"ok",
    "totalResults":38,
    "articles":[
        {
            "source":{
                "id":null,
                "name":"News-Medical.Net"
            },
            "author":null,
            "title":"Host tissue T cells play a previously unappreciated role in acute graft-versus-host disease - News-Medical.net",
            "description":"Allogenic hematopoietic stem cell transplantation (HSCT) is a procedure that infuses a donor's healthy blood-forming stem cells into a recipient as part of a potentially curative therapy for cancer.",
            "url":"https://www.news-medical.net/news/20200828/Host-tissue-T-cells-play-a-previously-unappreciated-role-in-acute-graft-versus-host-disease.aspx",
            "urlToImage":"https://www.news-medical.net/image.axd?picture=2014%2f7%2fChemo_Vials-620x480.jpg",
            "publishedAt":"2020-08-29T02:28:00Z",
            "content":"Reviewed by Emily Henderson, B.Sc.Aug 28 2020\r\nAllogenic hematopoietic stem cell transplantation (HSCT) is a procedure that infuses a donor's healthy blood-forming stem cells into a recipient as part… [+3762 chars]"
        },
        {
            "source":{
                "id":"abc-news-au",
                "name":"ABC News (AU)"
            },
            "author":"ABC News",
            "title":"Black Panther actor Chadwick Boseman dies of cancer - ABC News",
            "description":"Actor Chadwick Boseman, who played black icons Jackie Robinson and James Brown before finding fame as the regal Black Panther in the Marvel cinematic universe, dies of cancer.",
            "url":"https://www.abc.net.au/news/2020-08-29/chadwick-boseman,-black-panther-actor,-dies-of-cancer/12609278",
            "urlToImage":"https://www.abc.net.au/cm/rimage/12609312-16x9-large.jpg?v=2",
            "publishedAt":"2020-08-29T02:14:00Z",
            "content":"Actor Chadwick Boseman, who played black icons Jackie Robinson and James Brown before finding fame as the regal Black Panther in the Marvel cinematic universe, has died of cancer.\r\nHe was 42.\r\nBosema… [+651 chars]"
        },
        {
            "source":{
                "id":"abc-news-au",
                "name":"ABC News (AU)"
            },
            "author":"ABC News",
            "title":"Queensland records four more coronavirus cases - ABC News",
            "description":"Health Minister Steven Miles says Queensland has recorded four more cases of COVID-19 as a result of testing from the previous 24-hour period.",
            "url":"https://www.abc.net.au/news/2020-08-29/four-more-case-of-coronavirus-queensland/12607350",
            "urlToImage":"https://www.abc.net.au/cm/rimage/12159214-16x9-large.jpg?v=2",
            "publishedAt":"2020-08-29T01:57:00Z",
            "content":"Queensland has recorded four new cases of coronavirus as a result of testing in the past 24 hours. \r\nHealth Minister Steven Miles said all four cases were related to the known COVID-19 outbreak at th… [+2394 chars]"
        },
        // More results
    ]
}

而且,这看起来很熟悉。

因此,我将代码从上面修改为...

struct Source: Decodable {
    let id: String?
    let name: String
}

struct Article: Decodable {
    let author: String?
    let content: String?
    let description: String
    let publishedAt: Date
    let source: Source
    let title: String
    let url: URL
    let urlToImage: URL?
}

struct NewsAPIResponse: Decodable {
    let status: String
    let totalResults: Int
    let articles: [Article]
}

然后使用...

do {
    let url = URL(string: "https://newsapi.org/v2/top-headlines?country=au&apiKey=df4df715a25e4f8797914f036d2da5ec")!
    let data = try Data(contentsOf: url)
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .iso8601
    
    let response = try decoder.decode(NewsAPIResponse.self, from: data)
    
    for article in response.articles {
        print(article.source.name)
    }
} catch let error {
    print(error)
}

下载并解析它。

然后,我可以通过source的{​​{1}}属性来访问源,简单。