0

I am new to Swift programming and currently working on an app which will load Stock data which is in .json format. I am successfully able to load the "testStockData.json" into my code. Here is my parseJSON function within my ViewController:

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:

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:

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? How can i parse the JSON successfully? My goal is to be able to print each day "close" price to the output, so something like:

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:

{
    "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!

1 Answer 1

2

I like to use QuickType.io (https://app.quicktype.io) for this type of problem. You can input your JSON and it gives you a Swift structure:

// 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")
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.