Need a Swift Dictionary with more than a key value pair?
So here’s the problem I needed to solve to prevent a lot of existing code from breaking in one of my applications that use a dictionary.
I use a dictionary to store a key / value pair of post template types in my blogging application I am building. It works like this.
I have a JSON file that contains a list of template names and keys. This is used to display a list of templates to choose from. Then, later on it uses the associated key to tell the exporter which template to use. A snippet of the data looks like this
[{
"displayName": "Swift Post",
"keyName": "blog-post-swift"
}, {
"displayName": "Video Post",
"keyName": "blog-post-video"
}]
You get the idea, pretty straight forward. That is why I went with a dictionary.
The problem
However, I decided to feature creep my own application and make it work for multiple sites, so now I need a way to know which templates are for which sites.
Yup, that breaks the dictionary key / value pair right there. 1 + 1 now needs to = 3.
The Analysis
After a few cups of coffee and kicking around a few ideas, plus a few code branches to experiment and see just how much reworking would be needed, then realizing there had to be a simpler way.
I found it!
The Answer
Tuple to the rescue!
I know dictionaries can only have one key, but then it struck me that they can have types of whatever I want, that’s where the tuple comes in.
I just need to change
var myDictionary: String: String = :
To
var myDictionary: String: (String: String) = :
That will give me what I need, a simple container to hold the extra element, granted it’s not the most elegant solution, but it works with just minor changes to how I access the dictionary.
So now I can adapt my data snippet, this allows me to also have the same template on multiple sites without issue should I need it.
[{
"siteKey": "site1",
"displayName": "Swift Post",
"keyName": "blog-post-swift"
}, {
"siteKey": "site1",
"displayName": "Video Post",
"keyName": "blog-post-video"
}, {
"siteKey": "site2",
"displayName": "Default Post",
"keyName": "blog-post"
}]
There is one downside that I can see which is fine (for now) but might come back to bite me later, the key still has to be unique. I think I have a solution there if I need it though, maybe that is a future post in the making.
So next time you are stuck in a key / value bind, remember
Tuples are types too :)