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
Codable
protocol. OR
we decode an object that respects theCodable
protocol.
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?
}