I want to do something like that: access my dictionary values with a String enumeration. I am trying to overload the subscript of the dictionary but without success.
Accessing the dictionary:
let district = address[JsonKeys.district]
where JsonKeys is:
enum JsonKeys: String {
case key1
case key2
case key...
}
and my subscript overload is as follow:
extension Dictionary where Key: StringLiteralConvertible, Value: AnyObject {
subscript(index: FOJsonKeys) -> AnyObject {
get {
return self[ index.rawValue] as! AnyObject
}
}
}
I get the following message:
**Cannot subscript a value of type 'Dictionary<Key, Value>' with an index of type 'String'**
Where am I wrong?
PS: don't want to do this (this would correct the error, but the code is unreadable this way):
let district = address[JsonKeys.district.rawValue]
The dictionary is a Json parsed dictionary given to me by AlamoFire. I am pretty sure I can't change its type.
Try this:
Remember, with having constraint as
Key: StringLiteralConvertible
, the extension works for any Dictionaries with its Key conforming toStringLiteralConvertible
. (You know many types other thanString
conform toStringLiteralConvertible
.)To call subscript
self[]
, you need to pass a value of typeKey
.index.rawValue
isString
, which may not always be aKey
in the extension.So, the extension I have shown would work for some Dictionaries, would cause runtime crash for some other Dictionaries.
A little bit more type-safe way:
I know that this is an old question, but I'd thought I'd add an implementation that is easier to extend, reuse, and more lightweight
Based on this blog post
This approach only requires us to extend our dictionary once, rather than for each enum. Instead, each enum needs to conform to
UsesRawValue
. Now we can use it like this.The simplest approach is to just lift the dictionary into more context. The context in this case is "it only has keys from this enum." Lifting a type in Swift is very straightforward. Just wrap it in a struct.