A small extension for Foundation, making development easier

During the development process, the programmer quiet often comes across a dictionary like [String: Any] (server response as JSON) or [AnyHashable: Any] (userInfo upon push notification). At the same time, sometimes it is necessary to create a dictionary of this type, while it is undesirable to specify the key as String literal. A small extension for Dictionary presented below solves this problem and somewhat simplifies the development process.

It is much more convenient to refer to the dictionary by enum cases instead of usual strings. This, firstly, reduces likelihood of an error, and secondly, it simplifies the call, since autocomplete suggests possible options. For implementation, it is enough to declare new enum in the extension to the Dictionary and add subscript:

As a result, you can get the value of the dictionary both using a string and using a case of enumeration:

let dict: [String: Any] = ["data": 1, "id": 2, "type": 3]
let result = dict["type"]
let sameResult = dict[.type]

Quite often you can come across this type of code:

let dict: [String: Any] = ["data": 1, "id": 2, "type": 3]
let result = dict["id"] as? Int

Much more convenient to move the downcast to extension, the benefit of Swift language has ample opportunities for implementation. Must be declared subscript with generic type:

If there is such subscript, then there is no need to cast the value to the desired type. Accordingly, uses all the possibilities of Swift for type inference:

let dict: [String: Any] = ["data": 1, "id": 2, "type": 3]
someMethod(optionalIntegerArgument: dict[.id])XCTAssertEqual(dict[.type], 3)let result: Int? = dict["type"]
let sameResult: Int? = dict[.type]

Sometimes the opposite problem also arises — creating a dictionary, for example, [String: Any] (sending data to the server as request parameters). In this case, you should again prefer enumeration cases as dictionary keys instead of strings. But since enums can be different and declared in any convenient place of your program, then some method is required that performs mapping keys to strings:

In fact, this extension allows you to preform mapping to any rawValue implementing Hashable protocol, not only to strings. Therefore the extension is slightly more versatile. Nethertheless, the task was solved a little more gracefully.

enum Payment: String {
case cash, card, credit
}

let dict: [Payment: Double] = [.cash: 10, .card: 20, .credit: 0]
let result = dict.mappedToRawValues
XCTAssertEqual(result, ["cash": 10.0, "card": 20.0, "credit": 0.0])

As mentioned in the beginning, the extension is quite small, but simplifies the development process. Let me wish you a good day, and that’s it.