espenlg espenlg - 4 months ago 6x
iOS Question

How to do nested dictionaries in Swift

As a beginner to Swift I'm struggling with even the simplest things :( I've tried in so many ways to create a dictionary within a dictionary but it always fails.

The reason is a I want to fill a table with 10 items. Each item has a title, url, pageviews and unique users. String, string, int, int. I want to be able to both read the data and fill the tablecell by using IndexPath.row and I want to be able to update the data every 5th second based on input from a api with json content.

I was trying in Playground and ended up with:

var topArticleDetails:[String:AnyObject] = ["title":"","url":"","uniqueUsers":0,"events":0]
var topArticles:[Int:NSDictionary] = [0:topArticleDetails]

topArticleDetails["title"] = "Varden - Nyheter"
topArticleDetails["url"] = ""
topArticleDetails["uniqueUsers"] = 50
topArticleDetails["events"] = 100

topArticles[1] = topArticleDetails

and it seems to work fine, but when I add this to my ViewController I'm getting the error Instance member 'topArticleDetails' cannot be used on type 'ViewController'

Close but no cigar..

How can I solve this? Maybe there is a better way than the one I'm trying now. At the moment it's kinda working but instead of having a nested dictionary I've ended up with four seperate arrays like this:

var topArticlesTitle = [String]()
var topArticlesURL = [String]()
var topArticlesEvents = [Int]()
var topArticlesUniqueUsers = [Int]()

and I'm pretty sure there must be a better way.

>> UPDATE <<

In addition to the solutions provided below I found another one. It's so simple I'm ashamed but I guess it's a part of learning both Swift and OOP at the same time. If I removed the data I tried to enter into the variables when declaring them and just kept them empty it worked like a charm.

var topArticleDetails = [String:AnyObject]()
var topArticles = [Int:NSDictionary]()


Instead of using a dictionary inside a dictionary, you can use and struct array, for example:

struct Article {
    var title: String?
    var url: String?
    var: events: Int?
    var uniqueUsers: Int?

var topArticles = [Article]()

It is more easy to mantain than the dictionary inside dictionary because it will be easy to change your model.