简体   繁体   English

解析 iOS 的 Swift 内嵌套 JSON 对象中的数据时出现问题

[英]Problem with parsing data in nested JSON objects within Swift for iOS

I am new to Swift programming and currently working on an app which will load Stock data which is in.json format.我是 Swift 编程的新手,目前正在开发一个应用程序,该应用程序将加载采用.json 格式的股票数据。 I am successfully able to load the "testStockData.json" into my code.我成功地将“testStockData.json”加载到我的代码中。 Here is my parseJSON function within my ViewController:这是我的 ViewController 中的 parseJSON function:

func parseJSON(jsonData: Data?)
{
    // Note: jsonData has the contents of "testStockData.json"
    let decoder = JSONDecoder()
    
    do
    {
        let stockData = try decoder.decode(Stock.self, from: jsonData!)
        let tickerSymbol = stockData.metaData["Symbol"]!
        let companyName = stockData.metaData["Company"]!
        print("\(companyName) has ticker symbol: \(tickerSymbol)")
    } catch
    {
        print("Error in JSON parsing")
    }
}

I also have the following Codable Stock struct:我还有以下 Codable Stock 结构:

struct Stock : Codable {

    var metaData = [String:String]()
    
    private enum CodingKeys : String, CodingKey {
        case metaData = "Meta Data"
    }
    
}

When I run the above parseJSON function, I am successfully able to get the following printed in my output:当我运行上面的 parseJSON function 时,我可以成功地在我的 output 中打印以下内容:

Apple Inc. has ticker symbol: AAPL 

However I am not able to figure out how to load the nested JSON object for the "Time Series (Daily)" data?但是我无法弄清楚如何为“时间序列(每日)”数据加载嵌套的 JSON object 数据? How can i parse the JSON successfully?如何成功解析 JSON? My goal is to be able to print each day "close" price to the output, so something like:我的目标是能够每天打印 output 的“收盘价”,例如:

Apple Inc. has ticker symbol: AAPL 
On 2021-04-23, closing price of AAPL was $134.32
On 2021-04-22, closing price of AAPL was $131.94
On 2021-04-21, closing price of AAPL was $133.5
On 2021-04-20, closing price of AAPL was $133.11
On 2021-04-19, closing price of AAPL was $134.84

Here is my testStockData.json file:这是我的 testStockData.json 文件:

{
    "Meta Data": {
        "Symbol": "AAPL",
        "Company": "Apple Inc."
    },
    "Time Series (Daily)": {
            "2021-04-23": {
                "open" : "132.16",
                "high" : "135.12",
                "low"  : "132.16",
                "close": "134.32"
            },
            "2021-04-22": {
                "open" : "133.04",
                "high" : "134.15",
                "low"  : "131.41",
                "close": "131.94"
            },
            "2021-04-21": {
                "open" : "132.36",
                "high" : "133.75",
                "low"  : "131.3001",
                "close": "133.5"
            },
            "2021-04-20": {
                "open" : "135.02",
                "high" : "135.53",
                "low"  : "131.81",
                "close": "133.11"
            },
            "2021-04-19": {
                "open" : "133.51",
                "high" : "135.47",
                "low"  : "133.34",
                "close": "134.84"
            }
        }
}

Any guidance would be greatly appreciated!任何指导将不胜感激!

I like to use QuickType.io ( https://app.quicktype.io ) for this type of problem.对于这类问题,我喜欢使用 QuickType.io ( https://app.quicktype.io )。 You can input your JSON and it gives you a Swift structure:你可以输入你的 JSON 它给你一个 Swift 结构:

// MARK: - Welcome
struct Root: Codable {
    let metaData: MetaData
    let timeSeriesDaily: [String: TimeSeriesDaily]

    enum CodingKeys: String, CodingKey {
        case metaData = "Meta Data"
        case timeSeriesDaily = "Time Series (Daily)"
    }
}

// MARK: - MetaData
struct MetaData: Codable {
    let symbol, company: String

    enum CodingKeys: String, CodingKey {
        case symbol = "Symbol"
        case company = "Company"
    }
}

// MARK: - TimeSeriesDaily
struct TimeSeriesDaily: Codable {
    let timeSeriesDailyOpen, high, low, close: String

    enum CodingKeys: String, CodingKey {
        case timeSeriesDailyOpen = "open"
        case high, low, close
    }
}

Then, parsing is pretty straightforward:然后,解析非常简单:

do {
    let root = try JSONDecoder().decode(Root.self, from: jsonData)
    print("\(root.metaData.company) has a ticker symbol: \(root.metaData.symbol)")
    root.timeSeriesDaily.forEach { (key, value) in
        print("On \(key), closing price of \(root.metaData.symbol) was $\(value.close)")
    }
} catch {
    print("error")
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM