Encoding and Decoding JSON in Swift
aka “How to decode response from a JSON API”
Import the Foundation library. This will also work if SwiftUI or UIKit or imported.
import Foundation
Define a struct to represent the JSON data
struct Dog: Codable {
var name: String
var age: Int
}
The struct should use the Codable protocol. This is required both for encoding and decoding.
- We encode an object that respects the
Codableprotocol. ORwe decode an object that respects theCodableprotocol.
Decoding from JSON
The following is the JSON used in the example.
let json = """
{"name": "Tommy", "age": 6}
"""
Create a Data object to store the JSON data
let data = Data(json.utf8)
The example uses JSON input from a variable. API responses will be Data objects, so they don’t have to be converted into a Data object again.
Initialize a JSON decoder
let decoder = JSONDecoder()
Decode the JSON into an object
let decoder = decoder.decode(Dog.self, from: data)
The Xcode will warn about this expression throwing. So we’ll have to wrap it with a try.
let decoder = try? decoder.decode(Dog.self, from: data)
decoder will now be a JsonResponse object and will contain the fields x and y
Encoding to JSON
Represent a new dog.
let dog = Dog(name: "Peggy", age: 3)
Define an encoder
let encoder = JSONEncoder()
Encode the dog and ofcourse wrap it with a try.
let json = try encoder.encode(dog)
The result will be a Data object. The response can be verified by converting it to String.
print(String(data: encoded_json, encoding: .utf8)!)
Stuff to know
In the Dog struct, both name and age are defined as mandatory properties. This means that the intializer for Dog will expect both the properties to be passed to the initializer when creating the object.
If we expect JSON responses from APIs to be containing optional fields, then it is better to make the properties optional too. Example below indicates that the age field is optional.
struct Dog: Codable {
var name: String
var age: Int?
}