Overview
A Swift dictionary is a collection of unordered and unique key-value pairs. JSON is a lightweight and human-readable format for exchanging data.
If you want to convert a dictionary into JSON, this dictionary must conform to the Encodable
or the Codable
protocol. For example, a dictionary with values of type String
, Int
, Bool
, or any other standard library type that conforms to Codable
protocol can be converted to JSON. However, a dictionary with values of type UIImage
, UIView
, or any other custom type that does not conform to Codable
protocol cannot be converted to JSON unless you implement the required methods for encoding and decoding.
In Swift, you can turn a dictionary into JSON by using the JSONSerialization
class or the JSONEncoder
class. Let’s unveil them in this article, one by one.
Using the JSONSerialization class
The class brings to the table a method named JSONSerialization.data(withJSONObject:options:)
, which can convert a dictionary into JSON data (a Data
object). This method takes a dictionary (or any other Foundation
object that can be converted to JSON) and an optional writing option (such as .prettyPrinted
for formatting the output). It returns a Data
object that contains the JSON representation of the dictionary. When calling the method, you should use a try-catch
block to handle potential errors.
To convert the JSON data into a JSON string, just use theString(data:encoding:)
initializer. This initializer takes a Data
object and an encoding (such as .utf8
for Unicode
) and returns an optional String
object that contains the JSON text.
An example is worth more than a thousand words:
import Foundation
// a dictionary of people and their ages
let people = [
"Wolf Man": 999,
"Dracula": 100,
"Mummy": 1500,
"Sling Academy": 10
]
do {
// here jsonData is the dictionary encoded in JSON data
let jsonData:Data = try JSONSerialization.data(
withJSONObject: people,
options: .prettyPrinted
)
// get a JSON string from jsonData object
let jsonString:String = String(data: jsonData, encoding: .utf8)!
print(jsonString)
} catch {
print(error.localizedDescription)
}
Output:
{
"Wolf Man" : 999,
"Mummy" : 1500,
"Sling Academy" : 10,
"Dracula" : 100
}
Let’s take a closer look at the .prettyPrinted
option. This one is a writing option that specifies that the output uses white space and indentation to make the resulting data more readable. If this option isn’t set, the serialization generates the most compact possible JSON representation (a kind of one-long-line text without white spaces) like this:
{"Dracula":100,"Mummy":1500,"Wolf Man":999,"Sling Academy":10}
If you print jsonData
(an instance of the Data
class) instead of jsonString
, you will see the number of its bytes.
Using the JSONEncoder class
The JSONEncoder.encode(_:)
method can take a dictionary that conforms to the Encodable
or the Codable
protocol and returns a Data
object that contains the JSON representation of the input dictionary.
Example:
import Foundation
let dict = [
"key1": "value1",
"key2": "value2",
"key3": "value3",
]
do {
// here jsonData is the dictionary encoded in JSON data
let jsonData = try JSONEncoder().encode(dict)
// here jsonString is the dictionary converted to JSON string
if let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString)
}
} catch {
print(error.localizedDescription)
}
Output:
{"key1":"value1","key3":"value3","key2":"value2"}