json - 解析字典行为奇怪

标签 json swift dictionary swift4 alamofire

如果一个 key 值为 null 并且另一个键不为 null,则解析字典值。

来自 source 的值 如果 id 的值为 null,则名称键无法解析。如果 id 的值不是 null,那么它返回 name 值。

    {
    "status": "ok",
    "totalResults": 70,
    "articles": [
        {
            "source": {
                "id": null,
                "name": "Bloombergquint.com"
            },
            "author": "Aman Kapadia, Forum Bhatt",
            "title": "Infibeam Auditors Raise Questions On Loans To Vendors - BloombergQuint",
            "description": "Auditors to Infibeam Avenues raise questions about loans to vendors.",
            "url": "https://www.bloombergquint.com/business/infibeam-auditors-raise-questions-on-loans-to-vendors",
            "urlToImage": "https://images.assettype.com/bloombergquint%2F2018-02%2F11136839-3c0c-4356-b4d3-c918f4d417ad%2F323233043_1-9%20(1).jpg?rect=0%2C204%2C4000%2C2100&w=1200&auto=format%2Ccompress",
            "publishedAt": "2019-02-15T14:58:37Z",
            "content": "Auditors to Infibeam Avenues Ltd. raised questions about loans to vendors and how it recognises revenue in a fresh concern for the online retailer. SRBC & Co. LLP, the audit arm of EY, and Shah & Taparia sought more information to justify the rational… [+1985 chars]"
        },
        {
            "source": {
                "id": null,
                "name": "Moneycontrol.com"
            },
            "author": null,
            "title": "RBI lifts cap on FPI investments in corporate bonds - Moneycontrol.com",
            "description": "While the provision was aimed at incentivising FPIs to maintain a portfolio of assets, market feedback indicates that foreign portfolio investors (FPIs) have been constrained by this stipulation, the RBI said.",
            "url": "https://www.moneycontrol.com/news/business/rbi-lifts-cap-on-fpi-investments-in-corporate-bonds-3545571.html",
            "urlToImage": "https://static-news.moneycontrol.com/static-mcnews/2017/03/RBI-770x433.jpg",
            "publishedAt": "2019-02-15T13:26:00Z",
            "content": "The Reserve Bank of India (RBI) Friday withdrew the 20 per cent limit on investments by FPIs in corporate bonds of an entity with a view to encourage more foreign investments. As part of the review of the FPI investment in corporate debt undertaken in April 2… [+696 chars]"
        },
        {
            "source": {
                "id": null,
                "name": "Rushlane.com"
            },
            "author": "Rishabh Jain",
            "title": "2019 Honda Civic Review test drive - Still got the charm? - RushLane",
            "description": "Honda is back with the Civic in India. But does it have enough to attract those who love driving?",
            "url": "https://www.rushlane.com/2019-honda-civic-review-test-drive-12297473.html",
            "urlToImage": "https://www.rushlane.com/wp-content/uploads/2019/02/2019-honda-civic-review-test-drive-photos-specs-launch-price-14.jpg",
            "publishedAt": "2019-02-15T12:59:00Z",
            "content": "The Civic happens to be one of most loved brands from Honda in India. Globally too, it is one of those rare brands which have seen 10 proper generation changes. It is sold in multiple body types like Sedan, Coupe and Hatchback, however the Indian market only … [+8342 chars]"
        },
        {
            "source": {
                "id": null,
                "name": "Team-bhp.com"
            },
            "author": "Aditya Nadkarni",
            "title": "Maruti Swift, Dzire, Ertiga could get CNG variants - Team-BHP",
            "description": "According to a media report, Maruti Suzuki might introduce CNG variants of its cars in the years to come. The move could be taken in response to comply with the BS-VI emission norms, which are scheduled ...",
            "url": "https://www.team-bhp.com/news/maruti-swift-dzire-ertiga-could-get-cng-variants",
            "urlToImage": "https://www.team-bhp.com/sites/default/files/styles/large/public/1_639.jpg",
            "publishedAt": "2019-02-15T12:43:30Z",
            "content": "According to a media report, Maruti Suzuki might introduce CNG variants of its cars in the years to come. The move could be taken in response to comply with the BS-VI emission norms, which are scheduled to be implemented in 2020 and tighter fuel efficiency no… [+1119 chars]"
        }
   ]
}

模型类

private struct Headline: Decodable {
    let author: String
    let title: String
    let source: Source

    struct Source: Codable {
        var id : String
        var name : String
    }

    private enum CodingKeys: String, CodingKey {

        case author
        case title
        case source
    }
}

内部 View Controller

let url = ""
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .secondsSince1970
    // It is necessary for correct decoding. Timestamp -> Date.

        Alamofire.request(url, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil)
            .responseJSON { response in
                switch response.result {
                case .success:
//                    ??? how to assing here! access the value global????
                case .failure(let error):
                    print("Request failed with error: \(error)")
            }
        }
    }

在 cellForRowAt 内部

cell.lbl_NewsTitle?.text = headlines[indexPath.row].title
cell.lbl_NewsSource?.text = headlines[indexPath.row].source["name"]

它仅在 id 持有一些字符串值时打印,否则 source.name 返回 nil

任何人都可以建议为什么会这样吗? 我是第一次使用快速语言。 :(

最佳答案

对于Decodable,您必须添加伞形结构,并且必须在Headlineid 中声明authorSource 中作为可选,因为它们可以是 null。所有的 CodingKeys 都是合成的。

struct Response : Decodable {
    let status: String
    let totalResults: Int
    let articles: [Headline]
}

struct Headline: Decodable {
    let author: String?
    let title: String
    let source: Source
    let publishedAt : Date

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

日期解码策略必须是 .iso8601 而不是 .secondsSince1970

此代码将 articles 数组分配给数据源并在主线程上重新加载 TableView

let url = ""

    Alamofire.request(url).responseJSON { response in
        switch response.result {
        case .success:
            let decoder = JSONDecoder()
            decoder.dateDecodingStrategy = .iso8601
            do {
               let result = try decoder.decode(Response.self, from: response.data!)
               self.headlines = result.articles
               DispatchQueue.main.async {
                    self.tableView.reloadData()
               }
            } catch { print("Decoding error:", error) }
        case .failure(let error):
            print("Request failed with error: \(error)")
        }
    }
}

数据源数组必须声明为

var headlines = [Headline]()

cellForRowAt中写入

let headline = headlines[indexPath.row]
cell.lbl_NewsTitle?.text = headline.title
cell.lbl_NewsSource?.text = headline.source.name

关于json - 解析字典行为奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54685582/

相关文章:

Jqueryeach - 索引值总是从 0 开始吗​​?

ios - 在 UINavigationController[1] 中的 tabBar[1] 中转换一个 viewController

dictionary - 具有接收者函数回调的 Map 语法

jQuery ajaxForm 返回 .json 文件

json - 在平面列表中显示 JSON 数据

json - Golang Unmarshal slice of slice of ints

swift - 为什么覆盖 SKSpriteNode 子类的位置变量会减慢速度?

swift - Ubuntu 上的 PerfectLib : module does seem to reference obsolete generated interface

c# - 关于数据结构设计的问题

ios - 在数组上映射一个 void(非返回函数)