Maanas
Maanas

Reputation: 43

Iterate through nested dictionary of type String: Any

So basically I'm trying to build a financial app for myself using an external api.

I successfully decoded the json response and stored the object into a dictionary of type [String: Any]. Here is my sample output for my portfolio: I stored this as a Published variable

     "accounts" : [
       {
         "position" : some_number_of_shares,
         "avgCost" : some_decimal_number,
         "contract" : {
           "symbol" : "someString",
           "currency" : "USD",
           "conID" : some_Integer,
           "exchange" : "someString",
           "tradingClass" : "someString",
           "localSymbol" : "someString"
         },
         "account" : "someString"
       },
       {
         "position" : some_number_of_shares,
         "avgCost" : some_decimal_number,
         "contract" : {
           "tradingClass" : "someString",
           "exchange" : "someString",
           "localSymbol" : "someString",
           "symbol" : "someString",
           "currency" : "USD",
           "conID" : some_Integer
         },
         "account" : "someString"
       }
     ]
   }

I'm trying to display all of this information through a simple for i in loop, however it always gives me some error about subscripts, or something about casting. here is my loop

for (key) in self.apicall.positions["accounts"]! {
    print(key["account"])
    print(type(of: key))
}

I got multiple errors with this loop, but if I removed the key["account"] then I got

Position(avgCost: someFloat, account: "someString", position: someShares, contract: MyFirebase.Contract(exchange: "someString", currency: "someString", symbol: "someString", tradingClass: "someString", localSymbol: "someString", conID: someNumber))
Position

Position(avgCost: someFloat, account: "someString", position: someShares, contract: MyFirebase.Contract(exchange: "someString", currency: "someString", symbol: "someString", tradingClass: "someString", localSymbol: "someString", conID: someNumber))
Position 

I tried treating this as an object too but it wouldn't allow me. Let me know if you need an error message to debug this for me if I'm missing something absurdly obvious lol

Thanks so much for the help

Upvotes: 0

Views: 148

Answers (2)

Maanas
Maanas

Reputation: 43

I got it! So basically all I had to do was to fix my Published dictionary from:

@Published var positions = [String: [Any]]() 

to:

@Published var positions = [String: [Position]]() 

where my Position was a struct where I decoded my JSON Response.

Upvotes: 1

Azor234
Azor234

Reputation: 38

First, I don't think using a dictionary to store your api response is the right approach. We have the codable protocol to conform decoded JSON types to model objects. That would make debugging a bit easier, and would also clean up the code

Second, in your scenario, "key" will give you an index because "accounts" is of type array of objects. So you need to get the value, and then get the key

for index in self.apicall.positions["accounts"]! {
    let position = self.apicall.positions["accounts"]![index]
    // Here you can loop through the key, value of position object
    let avgCost = position["avgCost"]
    print(avgCost)
    print(type(of: avgCost))
}

Upvotes: 0

Related Questions